From 93fbc5de96d5f6c88e6c39da63ef35d2809660c3 Mon Sep 17 00:00:00 2001 From: hank121314 Date: Sun, 19 Feb 2023 23:06:14 +0800 Subject: [PATCH] Add boost::iostreams --- boost/core/bit.hpp | 595 ++++++++++++++ boost/integer/integer_log2.hpp | 117 +++ boost/integer/integer_mask.hpp | 134 ++++ boost/iostreams/categories.hpp | 175 ++++ boost/iostreams/chain.hpp | 594 ++++++++++++++ boost/iostreams/char_traits.hpp | 73 ++ boost/iostreams/checked_operations.hpp | 158 ++++ boost/iostreams/close.hpp | 253 ++++++ boost/iostreams/code_converter.hpp | 417 ++++++++++ boost/iostreams/combine.hpp | 260 ++++++ boost/iostreams/compose.hpp | 493 ++++++++++++ boost/iostreams/concepts.hpp | 129 +++ boost/iostreams/constants.hpp | 42 + boost/iostreams/copy.hpp | 248 ++++++ boost/iostreams/detail/absolute_path.hpp | 46 ++ boost/iostreams/detail/access_control.hpp | 87 ++ .../detail/adapter/concept_adapter.hpp | 287 +++++++ .../detail/adapter/device_adapter.hpp | 67 ++ .../detail/adapter/direct_adapter.hpp | 282 +++++++ .../detail/adapter/filter_adapter.hpp | 69 ++ .../iostreams/detail/adapter/mode_adapter.hpp | 117 +++ .../detail/adapter/non_blocking_adapter.hpp | 62 ++ .../adapter/output_iterator_adapter.hpp | 41 + .../detail/adapter/range_adapter.hpp | 187 +++++ boost/iostreams/detail/add_facet.hpp | 49 ++ boost/iostreams/detail/bool_trait_def.hpp | 49 ++ .../broken_overload_resolution/forward.hpp | 31 + .../broken_overload_resolution/stream.hpp | 184 +++++ .../stream_buffer.hpp | 189 +++++ boost/iostreams/detail/buffer.hpp | 229 ++++++ boost/iostreams/detail/call_traits.hpp | 32 + boost/iostreams/detail/char_traits.hpp | 63 ++ boost/iostreams/detail/codecvt_helper.hpp | 214 +++++ boost/iostreams/detail/codecvt_holder.hpp | 63 ++ boost/iostreams/detail/config/auto_link.hpp | 49 ++ boost/iostreams/detail/config/bzip2.hpp | 50 ++ boost/iostreams/detail/config/codecvt.hpp | 81 ++ .../detail/config/disable_warnings.hpp | 30 + boost/iostreams/detail/config/dyn_link.hpp | 46 ++ .../detail/config/enable_warnings.hpp | 18 + boost/iostreams/detail/config/fpos.hpp | 45 ++ boost/iostreams/detail/config/gcc.hpp | 27 + boost/iostreams/detail/config/limits.hpp | 19 + .../detail/config/overload_resolution.hpp | 30 + boost/iostreams/detail/config/rtl.hpp | 72 ++ .../detail/config/unreachable_return.hpp | 24 + .../iostreams/detail/config/wide_streams.hpp | 54 ++ .../iostreams/detail/config/windows_posix.hpp | 25 + boost/iostreams/detail/config/zlib.hpp | 50 ++ boost/iostreams/detail/counted_array.hpp | 74 ++ boost/iostreams/detail/current_directory.hpp | 65 ++ boost/iostreams/detail/default_arg.hpp | 21 + boost/iostreams/detail/dispatch.hpp | 41 + boost/iostreams/detail/double_object.hpp | 114 +++ boost/iostreams/detail/enable_if_stream.hpp | 33 + boost/iostreams/detail/error.hpp | 45 ++ boost/iostreams/detail/execute.hpp | 135 ++++ boost/iostreams/detail/file_handle.hpp | 32 + boost/iostreams/detail/forward.hpp | 113 +++ boost/iostreams/detail/fstream.hpp | 33 + boost/iostreams/detail/functional.hpp | 189 +++++ boost/iostreams/detail/ios.hpp | 65 ++ boost/iostreams/detail/iostream.hpp | 34 + boost/iostreams/detail/is_dereferenceable.hpp | 80 ++ boost/iostreams/detail/is_iterator_range.hpp | 34 + boost/iostreams/detail/newline.hpp | 32 + boost/iostreams/detail/optional.hpp | 114 +++ boost/iostreams/detail/param_type.hpp | 27 + boost/iostreams/detail/path.hpp | 214 +++++ boost/iostreams/detail/push.hpp | 153 ++++ boost/iostreams/detail/push_params.hpp | 21 + boost/iostreams/detail/resolve.hpp | 230 ++++++ boost/iostreams/detail/restrict_impl.hpp | 483 +++++++++++ boost/iostreams/detail/select.hpp | 86 ++ boost/iostreams/detail/select_by_size.hpp | 161 ++++ boost/iostreams/detail/streambuf.hpp | 34 + boost/iostreams/detail/streambuf/chainbuf.hpp | 113 +++ .../detail/streambuf/direct_streambuf.hpp | 311 +++++++ .../detail/streambuf/indirect_streambuf.hpp | 454 +++++++++++ .../detail/streambuf/linked_streambuf.hpp | 114 +++ boost/iostreams/detail/system_failure.hpp | 84 ++ boost/iostreams/detail/template_params.hpp | 26 + boost/iostreams/detail/translate_int_type.hpp | 62 ++ boost/iostreams/detail/wrap_unwrap.hpp | 98 +++ boost/iostreams/device/array.hpp | 133 +++ boost/iostreams/device/back_inserter.hpp | 41 + boost/iostreams/device/file.hpp | 191 +++++ boost/iostreams/device/file_descriptor.hpp | 325 ++++++++ boost/iostreams/device/mapped_file.hpp | 609 ++++++++++++++ boost/iostreams/device/null.hpp | 66 ++ boost/iostreams/filter/aggregate.hpp | 168 ++++ boost/iostreams/filter/bzip2.hpp | 431 ++++++++++ boost/iostreams/filter/counter.hpp | 82 ++ boost/iostreams/filter/grep.hpp | 109 +++ boost/iostreams/filter/gzip.hpp | 757 ++++++++++++++++++ boost/iostreams/filter/line.hpp | 221 +++++ boost/iostreams/filter/lzma.hpp | 376 +++++++++ boost/iostreams/filter/newline.hpp | 441 ++++++++++ boost/iostreams/filter/regex.hpp | 98 +++ boost/iostreams/filter/stdio.hpp | 84 ++ boost/iostreams/filter/symmetric.hpp | 311 +++++++ boost/iostreams/filter/test.hpp | 319 ++++++++ boost/iostreams/filter/zlib.hpp | 431 ++++++++++ boost/iostreams/filter/zstd.hpp | 363 +++++++++ boost/iostreams/filtering_stream.hpp | 187 +++++ boost/iostreams/filtering_streambuf.hpp | 70 ++ boost/iostreams/flush.hpp | 125 +++ boost/iostreams/get.hpp | 17 + boost/iostreams/imbue.hpp | 82 ++ boost/iostreams/input_sequence.hpp | 72 ++ boost/iostreams/invert.hpp | 167 ++++ boost/iostreams/operations.hpp | 26 + boost/iostreams/operations_fwd.hpp | 41 + boost/iostreams/optimal_buffer_size.hpp | 87 ++ boost/iostreams/output_sequence.hpp | 72 ++ boost/iostreams/pipeline.hpp | 114 +++ boost/iostreams/positioning.hpp | 117 +++ boost/iostreams/put.hpp | 17 + boost/iostreams/putback.hpp | 17 + boost/iostreams/read.hpp | 241 ++++++ boost/iostreams/restrict.hpp | 26 + boost/iostreams/seek.hpp | 180 +++++ boost/iostreams/skip.hpp | 112 +++ boost/iostreams/slice.hpp | 28 + boost/iostreams/stream.hpp | 171 ++++ boost/iostreams/stream_buffer.hpp | 116 +++ boost/iostreams/tee.hpp | 232 ++++++ boost/iostreams/traits.hpp | 363 +++++++++ boost/iostreams/traits_fwd.hpp | 111 +++ boost/iostreams/write.hpp | 165 ++++ boost/random/detail/config.hpp | 18 + boost/random/detail/const_mod.hpp | 216 +++++ boost/random/detail/disable_warnings.hpp | 29 + boost/random/detail/enable_warnings.hpp | 22 + boost/random/detail/generator_bits.hpp | 36 + boost/random/detail/integer_log2.hpp | 84 ++ boost/random/detail/large_arithmetic.hpp | 122 +++ boost/random/detail/operators.hpp | 84 ++ boost/random/detail/ptr_helper.hpp | 67 ++ boost/random/detail/seed.hpp | 113 +++ boost/random/detail/seed_impl.hpp | 397 +++++++++ boost/random/detail/signed_unsigned_tools.hpp | 89 ++ boost/random/linear_congruential.hpp | 468 +++++++++++ boost/random/traits.hpp | 107 +++ boost/random/uniform_01.hpp | 257 ++++++ boost/random/uniform_smallint.hpp | 306 +++++++ build.cmd | 1 + libs/iostreams/build/Jamfile.v2 | 129 +++ libs/iostreams/build/has_lzma_cputhreads.cpp | 10 + libs/iostreams/src/bzip2.cpp | 171 ++++ libs/iostreams/src/file_descriptor.cpp | 621 ++++++++++++++ libs/iostreams/src/gzip.cpp | 174 ++++ libs/iostreams/src/lzma.cpp | 171 ++++ libs/iostreams/src/mapped_file.cpp | 499 ++++++++++++ libs/iostreams/src/zlib.cpp | 188 +++++ libs/iostreams/src/zstd.cpp | 166 ++++ 156 files changed, 23638 insertions(+) create mode 100644 boost/core/bit.hpp create mode 100644 boost/integer/integer_log2.hpp create mode 100644 boost/integer/integer_mask.hpp create mode 100644 boost/iostreams/categories.hpp create mode 100644 boost/iostreams/chain.hpp create mode 100644 boost/iostreams/char_traits.hpp create mode 100644 boost/iostreams/checked_operations.hpp create mode 100644 boost/iostreams/close.hpp create mode 100644 boost/iostreams/code_converter.hpp create mode 100644 boost/iostreams/combine.hpp create mode 100644 boost/iostreams/compose.hpp create mode 100644 boost/iostreams/concepts.hpp create mode 100644 boost/iostreams/constants.hpp create mode 100644 boost/iostreams/copy.hpp create mode 100644 boost/iostreams/detail/absolute_path.hpp create mode 100644 boost/iostreams/detail/access_control.hpp create mode 100644 boost/iostreams/detail/adapter/concept_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/device_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/direct_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/filter_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/mode_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/non_blocking_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/output_iterator_adapter.hpp create mode 100644 boost/iostreams/detail/adapter/range_adapter.hpp create mode 100644 boost/iostreams/detail/add_facet.hpp create mode 100644 boost/iostreams/detail/bool_trait_def.hpp create mode 100644 boost/iostreams/detail/broken_overload_resolution/forward.hpp create mode 100644 boost/iostreams/detail/broken_overload_resolution/stream.hpp create mode 100644 boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp create mode 100644 boost/iostreams/detail/buffer.hpp create mode 100644 boost/iostreams/detail/call_traits.hpp create mode 100644 boost/iostreams/detail/char_traits.hpp create mode 100644 boost/iostreams/detail/codecvt_helper.hpp create mode 100644 boost/iostreams/detail/codecvt_holder.hpp create mode 100644 boost/iostreams/detail/config/auto_link.hpp create mode 100644 boost/iostreams/detail/config/bzip2.hpp create mode 100644 boost/iostreams/detail/config/codecvt.hpp create mode 100644 boost/iostreams/detail/config/disable_warnings.hpp create mode 100644 boost/iostreams/detail/config/dyn_link.hpp create mode 100644 boost/iostreams/detail/config/enable_warnings.hpp create mode 100644 boost/iostreams/detail/config/fpos.hpp create mode 100644 boost/iostreams/detail/config/gcc.hpp create mode 100644 boost/iostreams/detail/config/limits.hpp create mode 100644 boost/iostreams/detail/config/overload_resolution.hpp create mode 100644 boost/iostreams/detail/config/rtl.hpp create mode 100644 boost/iostreams/detail/config/unreachable_return.hpp create mode 100644 boost/iostreams/detail/config/wide_streams.hpp create mode 100644 boost/iostreams/detail/config/windows_posix.hpp create mode 100644 boost/iostreams/detail/config/zlib.hpp create mode 100644 boost/iostreams/detail/counted_array.hpp create mode 100644 boost/iostreams/detail/current_directory.hpp create mode 100644 boost/iostreams/detail/default_arg.hpp create mode 100644 boost/iostreams/detail/dispatch.hpp create mode 100644 boost/iostreams/detail/double_object.hpp create mode 100644 boost/iostreams/detail/enable_if_stream.hpp create mode 100644 boost/iostreams/detail/error.hpp create mode 100644 boost/iostreams/detail/execute.hpp create mode 100644 boost/iostreams/detail/file_handle.hpp create mode 100644 boost/iostreams/detail/forward.hpp create mode 100644 boost/iostreams/detail/fstream.hpp create mode 100644 boost/iostreams/detail/functional.hpp create mode 100644 boost/iostreams/detail/ios.hpp create mode 100644 boost/iostreams/detail/iostream.hpp create mode 100644 boost/iostreams/detail/is_dereferenceable.hpp create mode 100644 boost/iostreams/detail/is_iterator_range.hpp create mode 100644 boost/iostreams/detail/newline.hpp create mode 100644 boost/iostreams/detail/optional.hpp create mode 100644 boost/iostreams/detail/param_type.hpp create mode 100644 boost/iostreams/detail/path.hpp create mode 100644 boost/iostreams/detail/push.hpp create mode 100644 boost/iostreams/detail/push_params.hpp create mode 100644 boost/iostreams/detail/resolve.hpp create mode 100644 boost/iostreams/detail/restrict_impl.hpp create mode 100644 boost/iostreams/detail/select.hpp create mode 100644 boost/iostreams/detail/select_by_size.hpp create mode 100644 boost/iostreams/detail/streambuf.hpp create mode 100644 boost/iostreams/detail/streambuf/chainbuf.hpp create mode 100644 boost/iostreams/detail/streambuf/direct_streambuf.hpp create mode 100644 boost/iostreams/detail/streambuf/indirect_streambuf.hpp create mode 100644 boost/iostreams/detail/streambuf/linked_streambuf.hpp create mode 100644 boost/iostreams/detail/system_failure.hpp create mode 100644 boost/iostreams/detail/template_params.hpp create mode 100644 boost/iostreams/detail/translate_int_type.hpp create mode 100644 boost/iostreams/detail/wrap_unwrap.hpp create mode 100644 boost/iostreams/device/array.hpp create mode 100644 boost/iostreams/device/back_inserter.hpp create mode 100644 boost/iostreams/device/file.hpp create mode 100644 boost/iostreams/device/file_descriptor.hpp create mode 100644 boost/iostreams/device/mapped_file.hpp create mode 100644 boost/iostreams/device/null.hpp create mode 100644 boost/iostreams/filter/aggregate.hpp create mode 100644 boost/iostreams/filter/bzip2.hpp create mode 100644 boost/iostreams/filter/counter.hpp create mode 100644 boost/iostreams/filter/grep.hpp create mode 100644 boost/iostreams/filter/gzip.hpp create mode 100644 boost/iostreams/filter/line.hpp create mode 100644 boost/iostreams/filter/lzma.hpp create mode 100644 boost/iostreams/filter/newline.hpp create mode 100644 boost/iostreams/filter/regex.hpp create mode 100644 boost/iostreams/filter/stdio.hpp create mode 100644 boost/iostreams/filter/symmetric.hpp create mode 100644 boost/iostreams/filter/test.hpp create mode 100644 boost/iostreams/filter/zlib.hpp create mode 100644 boost/iostreams/filter/zstd.hpp create mode 100644 boost/iostreams/filtering_stream.hpp create mode 100644 boost/iostreams/filtering_streambuf.hpp create mode 100644 boost/iostreams/flush.hpp create mode 100644 boost/iostreams/get.hpp create mode 100644 boost/iostreams/imbue.hpp create mode 100644 boost/iostreams/input_sequence.hpp create mode 100644 boost/iostreams/invert.hpp create mode 100644 boost/iostreams/operations.hpp create mode 100644 boost/iostreams/operations_fwd.hpp create mode 100644 boost/iostreams/optimal_buffer_size.hpp create mode 100644 boost/iostreams/output_sequence.hpp create mode 100644 boost/iostreams/pipeline.hpp create mode 100644 boost/iostreams/positioning.hpp create mode 100644 boost/iostreams/put.hpp create mode 100644 boost/iostreams/putback.hpp create mode 100644 boost/iostreams/read.hpp create mode 100644 boost/iostreams/restrict.hpp create mode 100644 boost/iostreams/seek.hpp create mode 100644 boost/iostreams/skip.hpp create mode 100644 boost/iostreams/slice.hpp create mode 100644 boost/iostreams/stream.hpp create mode 100644 boost/iostreams/stream_buffer.hpp create mode 100644 boost/iostreams/tee.hpp create mode 100644 boost/iostreams/traits.hpp create mode 100644 boost/iostreams/traits_fwd.hpp create mode 100644 boost/iostreams/write.hpp create mode 100644 boost/random/detail/config.hpp create mode 100644 boost/random/detail/const_mod.hpp create mode 100644 boost/random/detail/disable_warnings.hpp create mode 100644 boost/random/detail/enable_warnings.hpp create mode 100644 boost/random/detail/generator_bits.hpp create mode 100644 boost/random/detail/integer_log2.hpp create mode 100644 boost/random/detail/large_arithmetic.hpp create mode 100644 boost/random/detail/operators.hpp create mode 100644 boost/random/detail/ptr_helper.hpp create mode 100644 boost/random/detail/seed.hpp create mode 100644 boost/random/detail/seed_impl.hpp create mode 100644 boost/random/detail/signed_unsigned_tools.hpp create mode 100644 boost/random/linear_congruential.hpp create mode 100644 boost/random/traits.hpp create mode 100644 boost/random/uniform_01.hpp create mode 100644 boost/random/uniform_smallint.hpp create mode 100644 libs/iostreams/build/Jamfile.v2 create mode 100644 libs/iostreams/build/has_lzma_cputhreads.cpp create mode 100644 libs/iostreams/src/bzip2.cpp create mode 100644 libs/iostreams/src/file_descriptor.cpp create mode 100644 libs/iostreams/src/gzip.cpp create mode 100644 libs/iostreams/src/lzma.cpp create mode 100644 libs/iostreams/src/mapped_file.cpp create mode 100644 libs/iostreams/src/zlib.cpp create mode 100644 libs/iostreams/src/zstd.cpp diff --git a/boost/core/bit.hpp b/boost/core/bit.hpp new file mode 100644 index 0000000..ddd435b --- /dev/null +++ b/boost/core/bit.hpp @@ -0,0 +1,595 @@ +#ifndef BOOST_CORE_BIT_HPP_INCLUDED +#define BOOST_CORE_BIT_HPP_INCLUDED + +// MS compatible compilers support #pragma once + +#if defined(_MSC_VER) && (_MSC_VER >= 1020) +# pragma once +#endif + +// boost/core/bit.hpp +// +// A portable version of the C++20 standard header +// +// Copyright 2020 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// https://www.boost.org/LICENSE_1_0.txt + +#include +#include +#include +#include +#include + +#if defined(_MSC_VER) + +# include +# pragma intrinsic(_BitScanForward) +# pragma intrinsic(_BitScanReverse) + +# if defined(_M_X64) +# pragma intrinsic(_BitScanForward64) +# pragma intrinsic(_BitScanReverse64) +# endif + +# pragma warning(push) +# pragma warning(disable: 4127) // conditional expression is constant +# pragma warning(disable: 4244) // conversion from int to T + +#endif // defined(_MSC_VER) + +namespace boost +{ +namespace core +{ + +// bit_cast + +template +To bit_cast( From const & from ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(To) == sizeof(From) ); + + To to; + std::memcpy( &to, &from, sizeof(To) ); + return to; +} + +// countl + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countl_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ) - ( std::numeric_limits::digits - std::numeric_limits::digits ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_clz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_clzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countl_zero( T x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +inline int countl_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ +#if defined(_MSC_VER) + + unsigned long r; + + if( _BitScanReverse( &r, x ) ) + { + return 31 - static_cast( r ); + } + else + { + return 32; + } + +#else + + static unsigned char const mod37[ 37 ] = { 32, 31, 6, 30, 9, 5, 0, 29, 16, 8, 2, 4, 21, 0, 19, 28, 25, 15, 0, 7, 10, 1, 17, 3, 22, 20, 26, 0, 11, 18, 23, 27, 12, 24, 13, 14, 0 }; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + return mod37[ x % 37 ]; + +#endif +} + +inline int countl_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ +#if defined(_MSC_VER) && defined(_M_X64) + + unsigned long r; + + if( _BitScanReverse64( &r, x ) ) + { + return 63 - static_cast( r ); + } + else + { + return 64; + } + +#else + + return static_cast( x >> 32 ) != 0? + boost::core::detail::countl_impl( static_cast( x >> 32 ) ): + boost::core::detail::countl_impl( static_cast( x ) ) + 32; + +#endif +} + +inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 24; +} + +inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countl_impl( static_cast( x ) ) - 16; +} + +} // namespace detail + +template +int countl_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countl_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT +{ + return boost::core::countl_zero( static_cast( ~x ) ); +} + +// countr + +#if defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CONSTEXPR inline int countr_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctz( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzl( x ): std::numeric_limits::digits; +} + +BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return x? __builtin_ctzll( x ): std::numeric_limits::digits; +} + +} // namespace detail + +template +BOOST_CONSTEXPR int countr_zero( T x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +inline int countr_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ +#if defined(_MSC_VER) + + unsigned long r; + + if( _BitScanForward( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 32; + } + +#else + + static unsigned char const mod37[ 37 ] = { 32, 0, 1, 26, 2, 23, 27, 0, 3, 16, 24, 30, 28, 11, 0, 13, 4, 7, 17, 0, 25, 22, 31, 15, 29, 10, 12, 6, 0, 21, 14, 9, 5, 20, 8, 19, 18 }; + return mod37[ ( -(boost::int32_t)x & x ) % 37 ]; + +#endif +} + +inline int countr_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ +#if defined(_MSC_VER) && defined(_M_X64) + + unsigned long r; + + if( _BitScanForward64( &r, x ) ) + { + return static_cast( r ); + } + else + { + return 64; + } + +#else + + return static_cast( x ) != 0? + boost::core::detail::countr_impl( static_cast( x ) ): + boost::core::detail::countr_impl( static_cast( x >> 32 ) ) + 32; + +#endif +} + +inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x100 ); +} + +inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT +{ + return boost::core::detail::countr_impl( static_cast( x ) | 0x10000 ); +} + +} // namespace detail + +template +int countr_zero( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(T) == sizeof(boost::uint8_t) || sizeof(T) == sizeof(boost::uint16_t) || sizeof(T) == sizeof(boost::uint32_t) || sizeof(T) == sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint8_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) ) + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::countr_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +template +BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT +{ + return boost::core::countr_zero( static_cast( ~x ) ); +} + +// popcount + +#if defined(__GNUC__) || defined(__clang__) + +#if defined(__clang__) && __clang_major__ * 100 + __clang_minor__ < 304 +# define BOOST_CORE_POPCOUNT_CONSTEXPR +#else +# define BOOST_CORE_POPCOUNT_CONSTEXPR BOOST_CONSTEXPR +#endif + +namespace detail +{ + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned char x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned short x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned int x ) BOOST_NOEXCEPT +{ + return __builtin_popcount( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( unsigned long x ) BOOST_NOEXCEPT +{ + return __builtin_popcountl( x ); +} + +BOOST_CORE_POPCOUNT_CONSTEXPR inline int popcount_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT +{ + return __builtin_popcountll( x ); +} + +} // namespace detail + +#undef BOOST_CORE_POPCOUNT_CONSTEXPR + +template +BOOST_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + return boost::core::detail::popcount_impl( x ); +} + +#else // defined(__GNUC__) || defined(__clang__) + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x55555555 ); + x = ( x & 0x33333333 ) + ( ( x >> 2 ) & 0x33333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F; + + return static_cast( ( x * 0x01010101 ) >> 24 ); +} + +BOOST_CXX14_CONSTEXPR inline int popcount_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + x = x - ( ( x >> 1 ) & 0x5555555555555555 ); + x = ( x & 0x3333333333333333 ) + ( ( x >> 2 ) & 0x3333333333333333 ); + x = ( x + ( x >> 4 ) ) & 0x0F0F0F0F0F0F0F0F; + + return static_cast( ( x * 0x0101010101010101 ) >> 56 ); +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR int popcount( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } + else + { + return boost::core::detail::popcount_impl( static_cast( x ) ); + } +} + +#endif // defined(__GNUC__) || defined(__clang__) + +// rotating + +template +BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT +{ + unsigned const mask = std::numeric_limits::digits - 1; + return x << (s & mask) | x >> ((-s) & mask); +} + +template +BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT +{ + unsigned const mask = std::numeric_limits::digits - 1; + return x >> (s & mask) | x << ((-s) & mask); +} + +// integral powers of 2 + +template +BOOST_CONSTEXPR bool has_single_bit( T x ) BOOST_NOEXCEPT +{ + return x != 0 && ( x & ( x - 1 ) ) == 0; +} + +// bit_width should return int, https://cplusplus.github.io/LWG/issue3656 + +template +BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT +{ + return static_cast( + std::numeric_limits::digits - boost::core::countl_zero( x ) ); +} + +template +BOOST_CONSTEXPR T bit_floor( T x ) BOOST_NOEXCEPT +{ + return x == 0? 0: T(1) << ( boost::core::bit_width( x ) - 1 ); +} + +namespace detail +{ + +BOOST_CXX14_CONSTEXPR inline boost::uint32_t bit_ceil_impl( boost::uint32_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + + ++x; + + return x; +} + +BOOST_CXX14_CONSTEXPR inline boost::uint64_t bit_ceil_impl( boost::uint64_t x ) BOOST_NOEXCEPT +{ + if( x == 0 ) + { + return 0; + } + + --x; + + x |= x >> 1; + x |= x >> 2; + x |= x >> 4; + x |= x >> 8; + x |= x >> 16; + x |= x >> 32; + + ++x; + + return x; +} + +} // namespace detail + +template +BOOST_CXX14_CONSTEXPR T bit_ceil( T x ) BOOST_NOEXCEPT +{ + BOOST_STATIC_ASSERT( sizeof(T) <= sizeof(boost::uint64_t) ); + + BOOST_IF_CONSTEXPR ( sizeof(T) <= sizeof(boost::uint32_t) ) + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } + else + { + return static_cast( boost::core::detail::bit_ceil_impl( static_cast( x ) ) ); + } +} + +// endian + +#if defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(__BYTE_ORDER__) && defined(__ORDER_PDP_ENDIAN__) && __BYTE_ORDER__ == __ORDER_PDP_ENDIAN__ + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#elif defined(__LITTLE_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#elif defined(__BIG_ENDIAN__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =big + +#elif defined(_MSC_VER) || defined(__i386__) || defined(__x86_64__) + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER =little + +#else + +# define BOOST_CORE_BIT_NATIVE_INITIALIZER + +#endif + +#if !defined(BOOST_NO_CXX11_SCOPED_ENUMS) + +enum class endian +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +typedef endian endian_type; + +#else + +namespace endian +{ + +enum type +{ + big, + little, + native BOOST_CORE_BIT_NATIVE_INITIALIZER +}; + +} // namespace endian + +typedef endian::type endian_type; + +#endif + +#undef BOOST_CORE_BIT_NATIVE_INITIALIZER + +} // namespace core +} // namespace boost + +#if defined(_MSC_VER) +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_CORE_BIT_HPP_INCLUDED diff --git a/boost/integer/integer_log2.hpp b/boost/integer/integer_log2.hpp new file mode 100644 index 0000000..8ca236f --- /dev/null +++ b/boost/integer/integer_log2.hpp @@ -0,0 +1,117 @@ +// ----------------------------------------------------------- +// integer_log2.hpp +// +// Gives the integer part of the logarithm, in base 2, of a +// given number. Behavior is undefined if the argument is <= 0. +// +// Copyright (c) 2003-2004, 2008 Gennaro Prota +// Copyright (c) 2022 Andrey Semashev +// +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) +// +// ----------------------------------------------------------- + +#ifndef BOOST_INTEGER_INTEGER_LOG2_HPP +#define BOOST_INTEGER_INTEGER_LOG2_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { +namespace detail { + +// helper to find the maximum power of two +// less than p +template< unsigned int p, unsigned int n, bool = ((2u * n) < p) > +struct max_pow2_less : + public max_pow2_less< p, 2u * n > +{ +}; + +template< unsigned int p, unsigned int n > +struct max_pow2_less< p, n, false > +{ + BOOST_STATIC_CONSTANT(unsigned int, value = n); +}; + +template< typename T > +inline typename boost::disable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x) +{ + unsigned int n = detail::max_pow2_less< + std::numeric_limits< T >::digits, + CHAR_BIT / 2u + >::value; + + int result = 0; + while (x != 1) + { + T t(x >> n); + if (t) + { + result += static_cast< int >(n); +#if !defined(BOOST_NO_CXX11_RVALUE_REFERENCES) + x = static_cast< T&& >(t); +#else + x = t; +#endif + } + n >>= 1u; + } + + return result; +} + +template< typename T > +inline typename boost::enable_if< boost::is_integral< T >, int >::type integer_log2_impl(T x) +{ + // We could simply rely on numeric_limits but sometimes + // Borland tries to use numeric_limits, because + // of its usual const-related problems in argument deduction + // - gps + return static_cast< int >((sizeof(T) * CHAR_BIT - 1u) - + boost::core::countl_zero(static_cast< typename boost::make_unsigned< T >::type >(x))); +} + +#if defined(BOOST_HAS_INT128) +// We need to provide explicit overloads for __int128 because (a) boost/core/bit.hpp currently does not support it and +// (b) std::numeric_limits are not specialized for __int128 in some standard libraries. +inline int integer_log2_impl(boost::uint128_type x) +{ + const boost::uint64_t x_hi = static_cast< boost::uint64_t >(x >> 64u); + if (x_hi != 0u) + return 127 - boost::core::countl_zero(x_hi); + else + return 63 - boost::core::countl_zero(static_cast< boost::uint64_t >(x)); +} + +inline int integer_log2_impl(boost::int128_type x) +{ + return detail::integer_log2_impl(static_cast< boost::uint128_type >(x)); +} +#endif // defined(BOOST_HAS_INT128) + +} // namespace detail + + +// ------------ +// integer_log2 +// ------------ +template< typename T > +inline int integer_log2(T x) +{ + BOOST_ASSERT(x > 0); + return detail::integer_log2_impl(x); +} + +} // namespace boost + +#endif // BOOST_INTEGER_INTEGER_LOG2_HPP diff --git a/boost/integer/integer_mask.hpp b/boost/integer/integer_mask.hpp new file mode 100644 index 0000000..3be5035 --- /dev/null +++ b/boost/integer/integer_mask.hpp @@ -0,0 +1,134 @@ +// Boost integer/integer_mask.hpp header file ------------------------------// + +// (C) Copyright Daryle Walker 2001. +// Distributed under the Boost Software License, Version 1.0. (See +// accompanying file LICENSE_1_0.txt or copy at +// https://www.boost.org/LICENSE_1_0.txt) + +// See https://www.boost.org for updates, documentation, and revision history. + +#ifndef BOOST_INTEGER_INTEGER_MASK_HPP +#define BOOST_INTEGER_INTEGER_MASK_HPP + +#include // self include + +#include // for BOOST_STATIC_CONSTANT +#include // for boost::uint_t + +#include // for UCHAR_MAX, etc. +#include // for std::size_t + +#include // for std::numeric_limits + +// +// We simply cannot include this header on gcc without getting copious warnings of the kind: +// +// boost/integer/integer_mask.hpp:93:35: warning: use of C99 long long integer constant +// +// And yet there is no other reasonable implementation, so we declare this a system header +// to suppress these warnings. +// +#if defined(__GNUC__) && (__GNUC__ >= 4) +#pragma GCC system_header +#endif + +namespace boost +{ + + +// Specified single-bit mask class declaration -----------------------------// +// (Lowest bit starts counting at 0.) + +template < std::size_t Bit > +struct high_bit_mask_t +{ + typedef typename uint_t<(Bit + 1)>::least least; + typedef typename uint_t<(Bit + 1)>::fast fast; + + BOOST_STATIC_CONSTANT( least, high_bit = (least( 1u ) << Bit) ); + BOOST_STATIC_CONSTANT( fast, high_bit_fast = (fast( 1u ) << Bit) ); + + BOOST_STATIC_CONSTANT( std::size_t, bit_position = Bit ); + +}; // boost::high_bit_mask_t + + +// Specified bit-block mask class declaration ------------------------------// +// Makes masks for the lowest N bits +// (Specializations are needed when N fills up a type.) + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4310) // cast truncates constant value +#endif + +template < std::size_t Bits > +struct low_bits_mask_t +{ + typedef typename uint_t::least least; + typedef typename uint_t::fast fast; + + BOOST_STATIC_CONSTANT( least, sig_bits = least(~(least(~(least( 0u ))) << Bits )) ); + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); + + BOOST_STATIC_CONSTANT( std::size_t, bit_count = Bits ); + +}; // boost::low_bits_mask_t + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#define BOOST_LOW_BITS_MASK_SPECIALIZE( Type ) \ + template < > struct low_bits_mask_t< std::numeric_limits::digits > { \ + typedef std::numeric_limits limits_type; \ + typedef uint_t::least least; \ + typedef uint_t::fast fast; \ + BOOST_STATIC_CONSTANT( least, sig_bits = (~( least(0u) )) ); \ + BOOST_STATIC_CONSTANT( fast, sig_bits_fast = fast(sig_bits) ); \ + BOOST_STATIC_CONSTANT( std::size_t, bit_count = limits_type::digits ); \ + } + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4245) // 'initializing' : conversion from 'int' to 'const boost::low_bits_mask_t<8>::least', signed/unsigned mismatch +#endif + +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned char ); + +#if USHRT_MAX > UCHAR_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned short ); +#endif + +#if UINT_MAX > USHRT_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned int ); +#endif + +#if ULONG_MAX > UINT_MAX +BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned long ); +#endif + +#if defined(BOOST_HAS_LONG_LONG) + #if ((defined(ULLONG_MAX) && (ULLONG_MAX > ULONG_MAX)) ||\ + (defined(ULONG_LONG_MAX) && (ULONG_LONG_MAX > ULONG_MAX)) ||\ + (defined(ULONGLONG_MAX) && (ULONGLONG_MAX > ULONG_MAX)) ||\ + (defined(_ULLONG_MAX) && (_ULLONG_MAX > ULONG_MAX))) + BOOST_LOW_BITS_MASK_SPECIALIZE( boost::ulong_long_type ); + #endif +#elif defined(BOOST_HAS_MS_INT64) + #if 18446744073709551615ui64 > ULONG_MAX + BOOST_LOW_BITS_MASK_SPECIALIZE( unsigned __int64 ); + #endif +#endif + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#undef BOOST_LOW_BITS_MASK_SPECIALIZE + + +} // namespace boost + + +#endif // BOOST_INTEGER_INTEGER_MASK_HPP diff --git a/boost/iostreams/categories.hpp b/boost/iostreams/categories.hpp new file mode 100644 index 0000000..0e84de1 --- /dev/null +++ b/boost/iostreams/categories.hpp @@ -0,0 +1,175 @@ +// (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. + +// Contains category and mode tags for classifying filters, devices and +// standard stream and stream buffers types. + +#ifndef BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED +#define BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +namespace boost { namespace iostreams { + +//------------------Tags for dispatch according to i/o mode-------------------// + +struct any_tag { }; +namespace detail { struct two_sequence : virtual any_tag { }; } +namespace detail { struct random_access : virtual any_tag { }; } +namespace detail { struct one_head : virtual any_tag { }; } +namespace detail { struct two_head : virtual any_tag { }; } +struct input : virtual any_tag { }; +struct output : virtual any_tag { }; +struct bidirectional : virtual input, virtual output, detail::two_sequence { }; +struct dual_use : virtual input, virtual output { }; // Pseudo-mode. +struct input_seekable : virtual input, virtual detail::random_access { }; +struct output_seekable : virtual output, virtual detail::random_access { }; +struct seekable + : virtual input_seekable, + virtual output_seekable, + detail::one_head + { }; +struct dual_seekable + : virtual input_seekable, + virtual output_seekable, + detail::two_head + { }; +struct bidirectional_seekable + : input_seekable, output_seekable, + bidirectional, detail::two_head + { }; + +//------------------Tags for use as i/o categories----------------------------// + +struct device_tag : virtual any_tag { }; +struct filter_tag : virtual any_tag { }; + + // + // Tags for optional behavior. + // + +struct peekable_tag : virtual any_tag { }; // Devices. +struct closable_tag : virtual any_tag { }; +struct flushable_tag : virtual any_tag { }; +struct localizable_tag : virtual any_tag { }; +struct optimally_buffered_tag : virtual any_tag { }; +struct direct_tag : virtual any_tag { }; // Devices. +struct multichar_tag : virtual any_tag { }; // Filters. + +struct source_tag : device_tag, input { }; +struct sink_tag : device_tag, output { }; +struct bidirectional_device_tag : device_tag, bidirectional { }; +struct seekable_device_tag : virtual device_tag, seekable { }; + +struct input_filter_tag : filter_tag, input { }; +struct output_filter_tag : filter_tag, output { }; +struct bidirectional_filter_tag : filter_tag, bidirectional { }; +struct seekable_filter_tag : filter_tag, seekable { }; +struct dual_use_filter_tag : filter_tag, dual_use { }; + +struct multichar_input_filter_tag + : multichar_tag, + input_filter_tag + { }; +struct multichar_output_filter_tag + : multichar_tag, + output_filter_tag + { }; +struct multichar_bidirectional_filter_tag + : multichar_tag, + bidirectional_filter_tag + { }; +struct multichar_seekable_filter_tag + : multichar_tag, + seekable_filter_tag + { }; +struct multichar_dual_use_filter_tag + : multichar_tag, + dual_use_filter_tag + { }; + + // + // Tags for standard streams and streambufs. + // + +struct std_io_tag : virtual localizable_tag { }; +struct istream_tag + : virtual device_tag, + virtual peekable_tag, + virtual std_io_tag + { }; +struct ostream_tag + : virtual device_tag, + virtual std_io_tag + { }; +struct iostream_tag + : istream_tag, + ostream_tag + { }; +struct streambuf_tag + : device_tag, + peekable_tag, + std_io_tag + { }; +struct ifstream_tag + : input_seekable, + closable_tag, + istream_tag + { }; +struct ofstream_tag + : output_seekable, + closable_tag, + ostream_tag + { }; +struct fstream_tag + : seekable, + closable_tag, + iostream_tag + { }; +struct filebuf_tag + : seekable, + closable_tag, + streambuf_tag + { }; +struct istringstream_tag + : input_seekable, + istream_tag + { }; +struct ostringstream_tag + : output_seekable, + ostream_tag + { }; +struct stringstream_tag + : dual_seekable, + iostream_tag + { }; +struct stringbuf_tag + : dual_seekable, + streambuf_tag + { }; +struct generic_istream_tag + : input_seekable, + istream_tag + { }; +struct generic_ostream_tag + : output_seekable, + ostream_tag + { }; +struct generic_iostream_tag + : seekable, + iostream_tag + { }; +struct generic_streambuf_tag + : seekable, + streambuf_tag + { }; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CATEGORIES_HPP_INCLUDED diff --git a/boost/iostreams/chain.hpp b/boost/iostreams/chain.hpp new file mode 100644 index 0000000..a7d7dd7 --- /dev/null +++ b/boost/iostreams/chain.hpp @@ -0,0 +1,594 @@ +// (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 BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include // advance. +#include +#include // allocator, auto_ptr or unique_ptr. +#include // logic_error, out_of_range. +#include +#include // BOOST_MSVC, template friends, +#include // BOOST_NESTED_TEMPLATE +#include +#include +#include +#include +#include +#include // pubsync. +#include +#include +#include +#include // is_filter. +#include +#include +#include +#include +#include +#include +#include +#include + +// Sometimes type_info objects must be compared by name. Borrowed from +// Boost.Python and Boost.Function. +#if defined(__GNUC__) || \ + defined(_AIX) || \ + (defined(__sgi) && defined(__host_mips)) || \ + (defined(linux) && defined(__INTEL_COMPILER) && defined(__ICC)) \ + /**/ +# include +# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) \ + (std::strcmp((X).name(),(Y).name()) == 0) +#else +# define BOOST_IOSTREAMS_COMPARE_TYPE_ID(X,Y) ((X)==(Y)) +#endif + +// Deprecated. Unused. +#define BOOST_IOSTREAMS_COMPONENT_TYPE(chain, index) \ + chain.component_type( index ) \ + /**/ + +// Deprecated. Unused. +#define BOOST_IOSTREAMS_COMPONENT(chain, index, target) \ + chain.component< target >( index ) \ + /**/ + +namespace boost { namespace iostreams { + +//--------------Definition of chain and wchain--------------------------------// + +namespace detail { + +template class chain_client; + +// +// Concept name: Chain. +// Description: Represents a chain of stream buffers which provides access +// to the first buffer in the chain and sends notifications when the +// streambufs are added to or removed from chain. +// Refines: Closable device with mode equal to typename Chain::mode. +// Models: chain, converting_chain. +// Example: +// +// class chain { +// public: +// typedef xxx chain_type; +// typedef xxx client_type; +// typedef xxx mode; +// bool is_complete() const; // Ready for i/o. +// template +// void push( const T& t, // Adds a stream buffer to +// streamsize, // chain, based on t, with +// streamsize ); // given buffer and putback +// // buffer sizes. Pass -1 to +// // request default size. +// protected: +// void register_client(client_type* client); // Associate client. +// void notify(); // Notify client. +// }; +// + +// +// Description: Represents a chain of filters with an optional device at the +// end. +// Template parameters: +// Self - A class deriving from the current instantiation of this template. +// This is an example of the Curiously Recurring Template Pattern. +// Ch - The character type. +// Tr - The character traits type. +// Alloc - The allocator type. +// Mode - A mode tag. +// +template +class chain_base { +public: + typedef Ch char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) + typedef Alloc allocator_type; + typedef Mode mode; + struct category + : Mode, + device_tag + { }; + typedef chain_client client_type; + friend class chain_client; +private: + typedef linked_streambuf streambuf_type; + typedef std::list list_type; + typedef chain_base my_type; +protected: + chain_base() : pimpl_(new chain_impl) { } + chain_base(const chain_base& rhs): pimpl_(rhs.pimpl_) { } +public: + + // dual_use is a pseudo-mode to facilitate filter writing, + // not a genuine mode. + BOOST_STATIC_ASSERT((!is_convertible::value)); + + //----------Buffer sizing-------------------------------------------------// + + // Sets the size of the buffer created for the devices to be added to this + // chain. Does not affect the size of the buffer for devices already + // added. + void set_device_buffer_size(std::streamsize n) + { pimpl_->device_buffer_size_ = n; } + + // Sets the size of the buffer created for the filters to be added + // to this chain. Does not affect the size of the buffer for filters already + // added. + void set_filter_buffer_size(std::streamsize n) + { pimpl_->filter_buffer_size_ = n; } + + // Sets the size of the putback buffer for filters and devices to be added + // to this chain. Does not affect the size of the buffer for filters or + // devices already added. + void set_pback_size(std::streamsize n) + { pimpl_->pback_size_ = n; } + + //----------Device interface----------------------------------------------// + + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); + + //----------Direct component access---------------------------------------// + + const boost::core::typeinfo& component_type(int n) const + { + if (static_cast(n) >= size()) + boost::throw_exception(std::out_of_range("bad chain offset")); + return (*boost::next(list().begin(), n))->component_type(); + } + + // Deprecated. + template + const boost::core::typeinfo& component_type() const { return component_type(N); } + + template + T* component(int n) const { return component(n, boost::type()); } + + // Deprecated. + template + T* component() const { return component(N); } + +#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310) + private: +#endif + template + T* component(int n, boost::type) const + { + if (static_cast(n) >= size()) + boost::throw_exception(std::out_of_range("bad chain offset")); + streambuf_type* link = *boost::next(list().begin(), n); + if (BOOST_IOSTREAMS_COMPARE_TYPE_ID(link->component_type(), BOOST_CORE_TYPEID(T))) + return static_cast(link->component_impl()); + else + return 0; + } +public: + + //----------Container-like interface--------------------------------------// + + typedef typename list_type::size_type size_type; + streambuf_type& front() { return *list().front(); } + BOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl) + void pop(); + bool empty() const { return list().empty(); } + size_type size() const { return list().size(); } + void reset(); + + //----------Additional i/o functions--------------------------------------// + + // Returns true if this chain is non-empty and its final link + // is a source or sink, i.e., if it is ready to perform i/o. + bool is_complete() const; + bool auto_close() const; + void set_auto_close(bool close); + bool sync() { return front().BOOST_IOSTREAMS_PUBSYNC() != -1; } + bool strict_sync(); +private: + template + void push_impl(const T& t, std::streamsize buffer_size = -1, + std::streamsize pback_size = -1) + { + typedef typename iostreams::category_of::type category; + typedef typename unwrap_ios::type component_type; + typedef stream_buffer< + component_type, + BOOST_IOSTREAMS_CHAR_TRAITS(char_type), + Alloc, Mode + > streambuf_t; + typedef typename list_type::iterator iterator; + BOOST_STATIC_ASSERT((is_convertible::value)); + if (is_complete()) + boost::throw_exception(std::logic_error("chain complete")); + streambuf_type* prev = !empty() ? list().back() : 0; + buffer_size = + buffer_size != -1 ? + buffer_size : + iostreams::optimal_buffer_size(t); + pback_size = + pback_size != -1 ? + pback_size : + pimpl_->pback_size_; + +#if defined(BOOST_NO_CXX11_SMART_PTR) + + std::auto_ptr + buf(new streambuf_t(t, buffer_size, pback_size)); + +#else + + std::unique_ptr + buf(new streambuf_t(t, buffer_size, pback_size)); + +#endif + + list().push_back(buf.get()); + buf.release(); + if (is_device::value) { + pimpl_->flags_ |= f_complete | f_open; + for ( iterator first = list().begin(), + last = list().end(); + first != last; + ++first ) + { + (*first)->set_needs_close(); + } + } + if (prev) prev->set_next(list().back()); + notify(); + } + + list_type& list() { return pimpl_->links_; } + const list_type& list() const { return pimpl_->links_; } + void register_client(client_type* client) { pimpl_->client_ = client; } + void notify() { if (pimpl_->client_) pimpl_->client_->notify(); } + + //----------Nested classes------------------------------------------------// + + static void close(streambuf_type* b, BOOST_IOS::openmode m) + { + if (m == BOOST_IOS::out && is_convertible::value) + b->BOOST_IOSTREAMS_PUBSYNC(); + b->close(m); + } + + static void set_next(streambuf_type* b, streambuf_type* next) + { b->set_next(next); } + + static void set_auto_close(streambuf_type* b, bool close) + { b->set_auto_close(close); } + + struct closer { + typedef streambuf_type* argument_type; + typedef void result_type; + closer(BOOST_IOS::openmode m) : mode_(m) { } + void operator() (streambuf_type* b) + { + close(b, mode_); + } + BOOST_IOS::openmode mode_; + }; + friend struct closer; + + enum flags { + f_complete = 1, + f_open = 2, + f_auto_close = 4 + }; + + struct chain_impl { + chain_impl() + : client_(0), device_buffer_size_(default_device_buffer_size), + filter_buffer_size_(default_filter_buffer_size), + pback_size_(default_pback_buffer_size), + flags_(f_auto_close) + { } + ~chain_impl() + { + try { close(); } catch (...) { } + try { reset(); } catch (...) { } + } + void close() + { + if ((flags_ & f_open) != 0) { + flags_ &= ~f_open; + stream_buffer< basic_null_device > null; + if ((flags_ & f_complete) == 0) { + null.open(basic_null_device()); + set_next(links_.back(), &null); + } + links_.front()->BOOST_IOSTREAMS_PUBSYNC(); + try { + boost::iostreams::detail::execute_foreach( + links_.rbegin(), links_.rend(), + closer(BOOST_IOS::in) + ); + } catch (...) { + try { + boost::iostreams::detail::execute_foreach( + links_.begin(), links_.end(), + closer(BOOST_IOS::out) + ); + } catch (...) { } + throw; + } + boost::iostreams::detail::execute_foreach( + links_.begin(), links_.end(), + closer(BOOST_IOS::out) + ); + } + } + void reset() + { + typedef typename list_type::iterator iterator; + for ( iterator first = links_.begin(), + last = links_.end(); + first != last; + ++first ) + { + if ( (flags_ & f_complete) == 0 || + (flags_ & f_auto_close) == 0 ) + { + set_auto_close(*first, false); + } + streambuf_type* buf = 0; + std::swap(buf, *first); + delete buf; + } + links_.clear(); + flags_ &= ~f_complete; + flags_ &= ~f_open; + } + list_type links_; + client_type* client_; + std::streamsize device_buffer_size_, + filter_buffer_size_, + pback_size_; + int flags_; + }; + friend struct chain_impl; + + //----------Member data---------------------------------------------------// + +private: + shared_ptr pimpl_; +}; + +} // End namespace detail. + +// +// Macro: BOOST_IOSTREAMS_DECL_CHAIN(name, category) +// Description: Defines a template derived from chain_base appropriate for a +// particular i/o category. The template has the following parameters: +// Ch - The character type. +// Tr - The character traits type. +// Alloc - The allocator type. +// Macro parameters: +// name_ - The name of the template to be defined. +// category_ - The i/o category of the template to be defined. +// +#define BOOST_IOSTREAMS_DECL_CHAIN(name_, default_char_) \ + template< typename Mode, typename Ch = default_char_, \ + typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ + typename Alloc = std::allocator > \ + class name_ : public boost::iostreams::detail::chain_base< \ + name_, \ + Ch, Tr, Alloc, Mode \ + > \ + { \ + public: \ + struct category : device_tag, Mode { }; \ + typedef Mode mode; \ + private: \ + typedef boost::iostreams::detail::chain_base< \ + name_, \ + Ch, Tr, Alloc, Mode \ + > base_type; \ + public: \ + typedef Ch char_type; \ + typedef Tr traits_type; \ + typedef typename traits_type::int_type int_type; \ + typedef typename traits_type::off_type off_type; \ + name_() { } \ + name_(const name_& rhs) : base_type(rhs) { } \ + name_& operator=(const name_& rhs) \ + { base_type::operator=(rhs); return *this; } \ + }; \ + /**/ +BOOST_IOSTREAMS_DECL_CHAIN(chain, char) +BOOST_IOSTREAMS_DECL_CHAIN(wchain, wchar_t) +#undef BOOST_IOSTREAMS_DECL_CHAIN + +//--------------Definition of chain_client------------------------------------// + +namespace detail { + +// +// Template name: chain_client +// Description: Class whose instances provide access to an underlying chain +// using an interface similar to the chains. +// Subclasses: the various stream and stream buffer templates. +// +template +class chain_client { +public: + typedef Chain chain_type; + typedef typename chain_type::char_type char_type; + typedef typename chain_type::traits_type traits_type; + typedef typename chain_type::size_type size_type; + typedef typename chain_type::mode mode; + + chain_client(chain_type* chn = 0) : chain_(chn ) { } + chain_client(chain_client* client) : chain_(client->chain_) { } + virtual ~chain_client() { } + + const boost::core::typeinfo& component_type(int n) const + { return chain_->component_type(n); } + + // Deprecated. + template + const boost::core::typeinfo& component_type() const + { return chain_->BOOST_NESTED_TEMPLATE component_type(); } + + template + T* component(int n) const + { return chain_->BOOST_NESTED_TEMPLATE component(n); } + + // Deprecated. + template + T* component() const + { return chain_->BOOST_NESTED_TEMPLATE component(); } + + bool is_complete() const { return chain_->is_complete(); } + bool auto_close() const { return chain_->auto_close(); } + void set_auto_close(bool close) { chain_->set_auto_close(close); } + bool strict_sync() { return chain_->strict_sync(); } + void set_device_buffer_size(std::streamsize n) + { chain_->set_device_buffer_size(n); } + void set_filter_buffer_size(std::streamsize n) + { chain_->set_filter_buffer_size(n); } + void set_pback_size(std::streamsize n) { chain_->set_pback_size(n); } + BOOST_IOSTREAMS_DEFINE_PUSH(push, mode, char_type, push_impl) + void pop() { chain_->pop(); } + bool empty() const { return chain_->empty(); } + size_type size() const { return chain_->size(); } + void reset() { chain_->reset(); } + + // Returns a copy of the underlying chain. + chain_type filters() { return *chain_; } + chain_type filters() const { return *chain_; } +protected: + template + void push_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) + { chain_->push(t BOOST_IOSTREAMS_PUSH_ARGS()); } + chain_type& ref() { return *chain_; } + void set_chain(chain_type* c) + { chain_ = c; chain_->register_client(this); } +#if !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) && \ + (!BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)) + template + friend class chain_base; +#else + public: +#endif + virtual void notify() { } +private: + chain_type* chain_; +}; + +//--------------Implementation of chain_base----------------------------------// + +template +inline std::streamsize chain_base::read + (char_type* s, std::streamsize n) +{ return iostreams::read(*list().front(), s, n); } + +template +inline std::streamsize chain_base::write + (const char_type* s, std::streamsize n) +{ return iostreams::write(*list().front(), s, n); } + +template +inline std::streampos chain_base::seek + (stream_offset off, BOOST_IOS::seekdir way) +{ return iostreams::seek(*list().front(), off, way); } + +template +void chain_base::reset() +{ + using namespace std; + pimpl_->close(); + pimpl_->reset(); +} + +template +bool chain_base::is_complete() const +{ + return (pimpl_->flags_ & f_complete) != 0; +} + +template +bool chain_base::auto_close() const +{ + return (pimpl_->flags_ & f_auto_close) != 0; +} + +template +void chain_base::set_auto_close(bool close) +{ + pimpl_->flags_ = + (pimpl_->flags_ & ~f_auto_close) | + (close ? f_auto_close : 0); +} + +template +bool chain_base::strict_sync() +{ + typedef typename list_type::iterator iterator; + bool result = true; + for ( iterator first = list().begin(), + last = list().end(); + first != last; + ++first ) + { + bool s = (*first)->strict_sync(); + result = result && s; + } + return result; +} + +template +void chain_base::pop() +{ + BOOST_ASSERT(!empty()); + if (auto_close()) + pimpl_->close(); + streambuf_type* buf = 0; + std::swap(buf, list().back()); + buf->set_auto_close(false); + buf->set_next(0); + delete buf; + list().pop_back(); + pimpl_->flags_ &= ~f_complete; + if (auto_close() || list().empty()) + pimpl_->flags_ &= ~f_open; +} + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAIN_HPP_INCLUDED diff --git a/boost/iostreams/char_traits.hpp b/boost/iostreams/char_traits.hpp new file mode 100644 index 0000000..76ddf9d --- /dev/null +++ b/boost/iostreams/char_traits.hpp @@ -0,0 +1,73 @@ +// (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 BOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include // EOF. +#include // std::char_traits. +#include +#include +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +# include +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::wint_t; } +#endif + +namespace boost { namespace iostreams { + +// Dinkumware that comes with QNX Momentics 6.3.0, 4.0.2, incorrectly defines +// the EOF and WEOF macros to not std:: qualify the wint_t type (and so does +// Sun C++ 5.8 + STLport 4). Fix by placing the def in this scope. +// NOTE: Use BOOST_WORKAROUND? +#if (defined(__QNX__) && defined(BOOST_DINKUMWARE_STDLIB)) \ + || defined(__SUNPRO_CC) +using ::std::wint_t; +#endif + +const int WOULD_BLOCK = (int) (EOF - 1); + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +const std::wint_t WWOULD_BLOCK = (std::wint_t) (WEOF - 1); +#endif + +template +struct char_traits; + +template<> +struct char_traits : BOOST_IOSTREAMS_CHAR_TRAITS(char) { + static char newline() { return '\n'; } + static int good() { return '\n'; } + static int would_block() { return WOULD_BLOCK; } + static bool is_good(int c) { return c != EOF && c != WOULD_BLOCK; } + static bool is_eof(int c) { return c == EOF; } + static bool would_block(int c) { return c == WOULD_BLOCK; } +}; + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +template<> +struct char_traits : std::char_traits { + static wchar_t newline() { return L'\n'; } + static std::wint_t good() { return L'\n'; } + static std::wint_t would_block() { return WWOULD_BLOCK; } + static bool is_good(std::wint_t c) { return c != WEOF && c != WWOULD_BLOCK; } + static bool is_eof(std::wint_t c) { return c == WEOF; } + static bool would_block(std::wint_t c) { return c == WWOULD_BLOCK; } +}; +#endif + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CHAR_TRAITS_HPP_INCLUDED diff --git a/boost/iostreams/checked_operations.hpp b/boost/iostreams/checked_operations.hpp new file mode 100644 index 0000000..667d925 --- /dev/null +++ b/boost/iostreams/checked_operations.hpp @@ -0,0 +1,158 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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. + +// Contains implementations of get, read, put, write and seek which +// check a device's mode at runtime instead of compile time. + +#ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct read_write_if_impl; + +template +struct seek_if_impl; + +} // End namespace detail. + +template +typename int_type_of::type get_if(T& t) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::get(t); +} + +template +inline std::streamsize +read_if(T& t, typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::read(t, s, n); +} + +template +bool put_if(T& t, typename char_type_of::type c) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::put(t, c); +} + +template +inline std::streamsize write_if + (T& t, const typename char_type_of::type* s, std::streamsize n) +{ + typedef typename detail::dispatch::type tag; + return detail::read_write_if_impl::write(t, s, n); +} + +template +inline std::streampos +seek_if( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + typedef typename dispatch::type tag; + return seek_if_impl::seek(t, off, way, which); +} + +namespace detail { + +//------------------Specializations of read_write_if_impl---------------------// + +template<> +struct read_write_if_impl { + template + static typename int_type_of::type get(T& t) + { return iostreams::get(t); } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return iostreams::read(t, s, n); } + + template + static bool put(T&, typename char_type_of::type) + { boost::throw_exception(cant_write()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(false) } + + template + static std::streamsize + write(T&, const typename char_type_of::type*, std::streamsize) + { boost::throw_exception(cant_write()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } +}; + +template<> +struct read_write_if_impl { + template + static typename int_type_of::type get(T&) + { boost::throw_exception(cant_read()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } + + template + static std::streamsize + read(T&, typename char_type_of::type*, std::streamsize) + { boost::throw_exception(cant_read()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } + + template + static bool put(T& t, typename char_type_of::type c) + { return iostreams::put(t, c); } + + template + static std::streamsize + write( T& t, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(t, s, n); } +}; + +//------------------Specializations of seek_if_impl---------------------------// + +template<> +struct seek_if_impl { + template + static std::streampos + seek( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return iostreams::seek(t, off, way, which); } +}; + +template<> +struct seek_if_impl { + template + static std::streampos + seek(T&, stream_offset, BOOST_IOS::seekdir, BOOST_IOS::openmode) + { boost::throw_exception(cant_seek()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(std::streampos()) } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED diff --git a/boost/iostreams/close.hpp b/boost/iostreams/close.hpp new file mode 100644 index 0000000..8ae499f --- /dev/null +++ b/boost/iostreams/close.hpp @@ -0,0 +1,253 @@ +// (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 BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED +#define BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // BOOST_IOS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +template +void close(T& t); + +template +void close(T& t, BOOST_IOS::openmode which); + +template +void close(T& t, Sink& snk, BOOST_IOS::openmode which); + +namespace detail { + +template +void close_all(T& t) +{ + try { + boost::iostreams::close(t, BOOST_IOS::in); + } catch (...) { + try { + boost::iostreams::close(t, BOOST_IOS::out); + } catch (...) { } + throw; + } + boost::iostreams::close(t, BOOST_IOS::out); +} + +template +void close_all(T& t, Sink& snk) +{ + try { + boost::iostreams::close(t, snk, BOOST_IOS::in); + } catch (...) { + try { + boost::iostreams::close(t, snk, BOOST_IOS::out); + } catch (...) { } + throw; + } + boost::iostreams::close(t, snk, BOOST_IOS::out); +} + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct close_impl; + +} // End namespace detail. + +template +void close(T& t) { detail::close_all(t); } + +template +void close(T& t, BOOST_IOS::openmode which) +{ +#ifdef BOOST_IOSTREAMS_STRICT + BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out); +#else + if (which == (BOOST_IOS::in | BOOST_IOS::out)) { + detail::close_all(t); + return; + } +#endif + detail::close_impl::close(detail::unwrap(t), which); +} + +template +void close(T& t, Sink& snk, BOOST_IOS::openmode which) +{ +#ifdef BOOST_IOSTREAMS_STRICT + BOOST_ASSERT(which == BOOST_IOS::in || which == BOOST_IOS::out); +#else + if (which == (BOOST_IOS::in | BOOST_IOS::out)) { + detail::close_all(t, snk); + return; + } +#endif + detail::close_impl::close(detail::unwrap(t), snk, which); +} + +namespace detail { + +//------------------Definition of close_impl----------------------------------// + +struct close_boost_stream { }; +struct close_filtering_stream { }; + +template +struct close_tag { + typedef typename category_of::type category; + typedef typename detail::unwrapped_type::type unwrapped; + typedef typename + iostreams::select< + mpl::not_< is_convertible >, + any_tag, + mpl::or_< + is_boost_stream, + is_boost_stream_buffer + >, + close_boost_stream, + mpl::or_< + is_filtering_stream, + is_filtering_streambuf + >, + close_filtering_stream, + mpl::or_< + is_convertible, + is_convertible + >, + two_sequence, + else_, + closable_tag + >::type type; +}; + +template +struct close_impl + : mpl::if_< + is_custom, + operations, + close_impl::type> + >::type + { }; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) + iostreams::flush(t); + } + + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) { + non_blocking_adapter nb(snk); + iostreams::flush(t, nb); + } + } +}; + +template<> +struct close_impl { + template + static void close(T& t) + { + t.close(); + } + template + static void close(T& t, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::out) + t.close(); + } +}; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in) && t.is_complete()) + t.pop(); + } +}; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) + t.close(); + } + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + typedef typename category_of::type category; + const bool in = is_convertible::value && + !is_convertible::value; + if (in == (which == BOOST_IOS::in)) { + non_blocking_adapter nb(snk); + t.close(nb); + } + } +}; + +template<> +struct close_impl { + template + static void close(T& t, BOOST_IOS::openmode which) { t.close(which); } + template + static void close(T& t, Sink& snk, BOOST_IOS::openmode which) + { + non_blocking_adapter nb(snk); + t.close(nb, which); + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED diff --git a/boost/iostreams/code_converter.hpp b/boost/iostreams/code_converter.hpp new file mode 100644 index 0000000..0bac461 --- /dev/null +++ b/boost/iostreams/code_converter.hpp @@ -0,0 +1,417 @@ +// (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. + +// Contains machinery for performing code conversion. + +#ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#if defined(BOOST_IOSTREAMS_NO_WIDE_STREAMS) || \ + defined(BOOST_IOSTREAMS_NO_LOCALE) \ + /**/ +# error code conversion not supported on this platform +#endif + +#include // max. +#include // memcpy. +#include +#include // DEDUCED_TYPENAME, +#include +#include // default_filter_buffer_size. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // failure, openmode, int types, streamsize. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // Borland 5.x + +namespace boost { namespace iostreams { + +struct code_conversion_error : BOOST_IOSTREAMS_FAILURE { + code_conversion_error() + : BOOST_IOSTREAMS_FAILURE("code conversion error") + { } +}; + +namespace detail { + +//--------------Definition of strncpy_if_same---------------------------------// + +// Helper template for strncpy_if_same, below. +template +struct strncpy_if_same_impl; + +template<> +struct strncpy_if_same_impl { + template + static Ch* copy(Ch* tgt, const Ch* src, std::streamsize n) + { return BOOST_IOSTREAMS_CHAR_TRAITS(Ch)::copy(tgt, src, n); } +}; + +template<> +struct strncpy_if_same_impl { + template + static Tgt* copy(Tgt* tgt, const Src*, std::streamsize) { return tgt; } +}; + +template +Tgt* strncpy_if_same(Tgt* tgt, const Src* src, std::streamsize n) +{ + typedef strncpy_if_same_impl::value> impl; + return impl::copy(tgt, src, n); +} + +//--------------Definition of conversion_buffer-------------------------------// + +// Buffer and conversion state for reading. +template +class conversion_buffer + : public buffer< + BOOST_DEDUCED_TYPENAME detail::codecvt_extern::type, + Alloc + > +{ +public: + typedef typename Codecvt::state_type state_type; + conversion_buffer() + : buffer< + BOOST_DEDUCED_TYPENAME detail::codecvt_extern::type, + Alloc + >(0) + { + reset(); + } + state_type& state() { return state_; } + void reset() + { + if (this->size()) + this->set(0, 0); + state_ = state_type(); + } +private: + state_type state_; +}; + +//--------------Definition of converter_impl----------------------------------// + +// Contains member data, open/is_open/close and buffer management functions. +template +struct code_converter_impl { + typedef typename codecvt_extern::type extern_type; + typedef typename category_of::type device_category; + typedef is_convertible can_read; + typedef is_convertible can_write; + typedef is_convertible is_bidir; + typedef typename + iostreams::select< // Disambiguation for Tru64. + is_bidir, bidirectional, + can_read, input, + can_write, output + >::type mode; + typedef typename + mpl::if_< + is_direct, + direct_adapter, + Device + >::type device_type; + typedef optional< concept_adapter > storage_type; + typedef is_convertible is_double; + typedef conversion_buffer buffer_type; + + code_converter_impl() : cvt_(), flags_(0) { } + + ~code_converter_impl() + { + try { + if (flags_ & f_open) close(); + } catch (...) { /* */ } + } + + template + void open(const T& dev, std::streamsize buffer_size) + { + if (flags_ & f_open) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("already open")); + if (buffer_size == -1) + buffer_size = default_filter_buffer_size; + std::streamsize max_length = cvt_.get().max_length(); + buffer_size = (std::max)(buffer_size, 2 * max_length); + if (can_read::value) { + buf_.first().resize(buffer_size); + buf_.first().set(0, 0); + } + if (can_write::value && !is_double::value) { + buf_.second().resize(buffer_size); + buf_.second().set(0, 0); + } + dev_.reset(concept_adapter(dev)); + flags_ = f_open; + } + + void close() + { + detail::execute_all( + detail::call_member_close(*this, BOOST_IOS::in), + detail::call_member_close(*this, BOOST_IOS::out) + ); + } + + void close(BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::in && (flags_ & f_input_closed) == 0) { + flags_ |= f_input_closed; + iostreams::close(dev(), BOOST_IOS::in); + } + if (which == BOOST_IOS::out && (flags_ & f_output_closed) == 0) { + flags_ |= f_output_closed; + detail::execute_all( + detail::flush_buffer(buf_.second(), dev(), can_write::value), + detail::call_close(dev(), BOOST_IOS::out), + detail::call_reset(dev_), + detail::call_reset(buf_.first()), + detail::call_reset(buf_.second()) + ); + } + } + + bool is_open() const { return (flags_ & f_open) != 0;} + + device_type& dev() { return **dev_; } + + enum flag_type { + f_open = 1, + f_input_closed = f_open << 1, + f_output_closed = f_input_closed << 1 + }; + + codecvt_holder cvt_; + storage_type dev_; + double_object< + buffer_type, + is_double + > buf_; + int flags_; +}; + +} // End namespace detail. + +//--------------Definition of converter---------------------------------------// + +#define BOOST_IOSTREAMS_CONVERTER_PARAMS() , std::streamsize buffer_size = -1 +#define BOOST_IOSTREAMS_CONVERTER_ARGS() , buffer_size + +template +struct code_converter_base { + typedef detail::code_converter_impl< + Device, Codecvt, Alloc + > impl_type; + code_converter_base() : pimpl_(new impl_type) { } + shared_ptr pimpl_; +}; + +template< typename Device, + typename Codecvt = detail::default_codecvt, + typename Alloc = std::allocator > +class code_converter + : protected code_converter_base +{ +private: + typedef detail::code_converter_impl< + Device, Codecvt, Alloc + > impl_type; + typedef typename impl_type::device_type device_type; + typedef typename impl_type::buffer_type buffer_type; + typedef typename detail::codecvt_holder::codecvt_type codecvt_type; + typedef typename detail::codecvt_intern::type intern_type; + typedef typename detail::codecvt_extern::type extern_type; + typedef typename detail::codecvt_state::type state_type; +public: + typedef intern_type char_type; + struct category + : impl_type::mode, device_tag, closable_tag, localizable_tag + { }; + BOOST_STATIC_ASSERT(( + is_same< + extern_type, + BOOST_DEDUCED_TYPENAME char_type_of::type + >::value + )); +public: + code_converter() { } + BOOST_IOSTREAMS_FORWARD( code_converter, open_impl, Device, + BOOST_IOSTREAMS_CONVERTER_PARAMS, + BOOST_IOSTREAMS_CONVERTER_ARGS ) + + // fstream-like interface. + + bool is_open() const { return this->pimpl_->is_open(); } + void close(BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) + { impl().close(which); } + + // Device interface. + + std::streamsize read(char_type*, std::streamsize); + std::streamsize write(const char_type*, std::streamsize); + void imbue(const std::locale& loc) { impl().cvt_.imbue(loc); } + + // Direct device access. + + Device& operator*() { return detail::unwrap_direct(dev()); } + Device* operator->() { return &detail::unwrap_direct(dev()); } +private: + template // Used for forwarding. + void open_impl(const T& t BOOST_IOSTREAMS_CONVERTER_PARAMS()) + { + impl().open(t BOOST_IOSTREAMS_CONVERTER_ARGS()); + } + + const codecvt_type& cvt() { return impl().cvt_.get(); } + device_type& dev() { return impl().dev(); } + buffer_type& in() { return impl().buf_.first(); } + buffer_type& out() { return impl().buf_.second(); } + impl_type& impl() { return *this->pimpl_; } +}; + +//--------------Implementation of converter-----------------------------------// + +// Implementation note: if end of stream contains a partial character, +// it is ignored. +template +std::streamsize code_converter::read + (char_type* s, std::streamsize n) +{ + const extern_type* next; // Next external char. + intern_type* nint; // Next internal char. + std::streamsize total = 0; // Characters read. + int status = iostreams::char_traits::good(); + bool partial = false; + buffer_type& buf = in(); + + do { + + // Fill buffer. + if (buf.ptr() == buf.eptr() || partial) { + status = buf.fill(dev()); + if (buf.ptr() == buf.eptr()) + break; + partial = false; + } + + // Convert. + std::codecvt_base::result result = + cvt().in( buf.state(), + buf.ptr(), buf.eptr(), next, + s + total, s + n, nint ); + buf.ptr() += next - buf.ptr(); + total = static_cast(nint - s); + + switch (result) { + case std::codecvt_base::partial: + partial = true; + break; + case std::codecvt_base::ok: + break; + case std::codecvt_base::noconv: + { + std::streamsize amt = + std::min(next - buf.ptr(), n - total); + detail::strncpy_if_same(s + total, buf.ptr(), amt); + total += amt; + } + break; + case std::codecvt_base::error: + default: + buf.state() = state_type(); + boost::throw_exception(code_conversion_error()); + } + + } while (total < n && status != EOF && status != WOULD_BLOCK); + + return total == 0 && status == EOF ? -1 : total; +} + +template +std::streamsize code_converter::write + (const char_type* s, std::streamsize n) +{ + buffer_type& buf = out(); + extern_type* next; // Next external char. + const intern_type* nint; // Next internal char. + std::streamsize total = 0; // Characters written. + bool partial = false; + + while (total < n) { + + // Empty buffer. + if (buf.eptr() == buf.end() || partial) { + if (!buf.flush(dev())) + break; + partial = false; + } + + // Convert. + std::codecvt_base::result result = + cvt().out( buf.state(), + s + total, s + n, nint, + buf.eptr(), buf.end(), next ); + int progress = (int) (next - buf.eptr()); + buf.eptr() += progress; + + switch (result) { + case std::codecvt_base::partial: + partial = true; + BOOST_FALLTHROUGH; + case std::codecvt_base::ok: + total = static_cast(nint - s); + break; + case std::codecvt_base::noconv: + { + std::streamsize amt = + std::min( nint - total - s, + buf.end() - buf.eptr() ); + detail::strncpy_if_same(buf.eptr(), s + total, amt); + total += amt; + } + break; + case std::codecvt_base::error: + default: + buf.state() = state_type(); + boost::throw_exception(code_conversion_error()); + } + } + return total; +} + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Borland 5.x + +#endif // #ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED diff --git a/boost/iostreams/combine.hpp b/boost/iostreams/combine.hpp new file mode 100644 index 0000000..107122a --- /dev/null +++ b/boost/iostreams/combine.hpp @@ -0,0 +1,260 @@ +// (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. + +// To do: add support for random-access. + +#ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED +#define BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // NO_STD_LOCALE, DEDUCED_TYPENAME. +#ifndef BOOST_NO_STD_LOCALE +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +// +// Template name: combined_device. +// Description: Model of Device defined in terms of a Source/Sink pair. +// Template parameters: +// Source - A model of Source, with the same char_type and traits_type +// as Sink. +// Sink - A model of Sink, with the same char_type and traits_type +// as Source. +// +template +class combined_device { +private: + typedef typename category_of::type in_category; + typedef typename category_of::type out_category; + typedef typename char_type_of::type sink_char_type; +public: + typedef typename char_type_of::type char_type; + struct category + : bidirectional, + device_tag, + closable_tag, + localizable_tag + { }; + BOOST_STATIC_ASSERT(is_device::value); + BOOST_STATIC_ASSERT(is_device::value); + BOOST_STATIC_ASSERT((is_convertible::value)); + BOOST_STATIC_ASSERT((is_convertible::value)); + BOOST_STATIC_ASSERT((is_same::value)); + combined_device(const Source& src, const Sink& snk); + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + void close(BOOST_IOS::openmode); + #ifndef BOOST_NO_STD_LOCALE + void imbue(const std::locale& loc); + #endif +private: + Source src_; + Sink sink_; +}; + +// +// Template name: combined_filter. +// Description: Model of Device defined in terms of a Source/Sink pair. +// Template parameters: +// InputFilter - A model of InputFilter, with the same char_type as +// OutputFilter. +// OutputFilter - A model of OutputFilter, with the same char_type as +// InputFilter. +// +template +class combined_filter { +private: + typedef typename category_of::type in_category; + typedef typename category_of::type out_category; + typedef typename char_type_of::type output_char_type; +public: + typedef typename char_type_of::type char_type; + struct category + : multichar_bidirectional_filter_tag, + closable_tag, + localizable_tag + { }; + BOOST_STATIC_ASSERT(is_filter::value); + BOOST_STATIC_ASSERT(is_filter::value); + BOOST_STATIC_ASSERT((is_convertible::value)); + BOOST_STATIC_ASSERT((is_convertible::value)); + BOOST_STATIC_ASSERT((is_same::value)); + combined_filter(const InputFilter& in, const OutputFilter& out); + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { return boost::iostreams::read(in_, src, s, n); } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { return boost::iostreams::write(out_, snk, s, n); } + + template + void close(Sink& snk, BOOST_IOS::openmode which) + { + if (which == BOOST_IOS::in) { + if (is_convertible::value) { + iostreams::close(in_, snk, BOOST_IOS::in); + } else { + detail::close_all(in_, snk); + } + } + if (which == BOOST_IOS::out) { + if (is_convertible::value) { + iostreams::close(out_, snk, BOOST_IOS::out); + } else { + detail::close_all(out_, snk); + } + } + } + #ifndef BOOST_NO_STD_LOCALE + void imbue(const std::locale& loc); + #endif +private: + InputFilter in_; + OutputFilter out_; +}; + +template +struct combination_traits + : mpl::if_< + is_device, + combined_device< + typename wrapped_type::type, + typename wrapped_type::type + >, + combined_filter< + typename wrapped_type::type, + typename wrapped_type::type + > + > + { }; + +} // End namespace detail. + +template +struct combination : detail::combination_traits::type { + typedef typename detail::combination_traits::type base_type; + typedef typename detail::wrapped_type::type in_type; + typedef typename detail::wrapped_type::type out_type; + combination(const in_type& in, const out_type& out) + : base_type(in, out) { } +}; + +namespace detail { + +// Workaround for VC6 ETI bug. +template +struct combine_traits { + typedef combination< + BOOST_DEDUCED_TYPENAME detail::unwrapped_type::type, + BOOST_DEDUCED_TYPENAME detail::unwrapped_type::type + > type; +}; + +} // End namespace detail. + +// +// Template name: combine. +// Description: Takes a Source/Sink pair or InputFilter/OutputFilter pair and +// returns a Source or Filter which performs input using the first member +// of the pair and output using the second member of the pair. +// Template parameters: +// In - A model of Source or InputFilter, with the same char_type as Out. +// Out - A model of Sink or OutputFilter, with the same char_type as In. +// +template +typename detail::combine_traits::type +combine(const In& in, const Out& out) +{ + typedef typename detail::combine_traits::type return_type; + return return_type(in, out); +} + +//----------------------------------------------------------------------------// + +namespace detail { + +//--------------Implementation of combined_device-----------------------------// + +template +inline combined_device::combined_device + (const Source& src, const Sink& snk) + : src_(src), sink_(snk) { } + +template +inline std::streamsize +combined_device::read(char_type* s, std::streamsize n) +{ return iostreams::read(src_, s, n); } + +template +inline std::streamsize +combined_device::write(const char_type* s, std::streamsize n) +{ return iostreams::write(sink_, s, n); } + +template +inline void +combined_device::close(BOOST_IOS::openmode which) +{ + if (which == BOOST_IOS::in) + detail::close_all(src_); + if (which == BOOST_IOS::out) + detail::close_all(sink_); +} + +#ifndef BOOST_NO_STD_LOCALE + template + void combined_device::imbue(const std::locale& loc) + { + iostreams::imbue(src_, loc); + iostreams::imbue(sink_, loc); + } +#endif + +//--------------Implementation of filter_pair---------------------------------// + +template +inline combined_filter::combined_filter + (const InputFilter& in, const OutputFilter& out) : in_(in), out_(out) + { } + +#ifndef BOOST_NO_STD_LOCALE + template + void combined_filter::imbue + (const std::locale& loc) + { + iostreams::imbue(in_, loc); + iostreams::imbue(out_, loc); + } +#endif + + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED diff --git a/boost/iostreams/compose.hpp b/boost/iostreams/compose.hpp new file mode 100644 index 0000000..fe9ae28 --- /dev/null +++ b/boost/iostreams/compose.hpp @@ -0,0 +1,493 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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. + +// Note: bidirectional streams are not supported. + +#ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED +#define BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // min. +#include // pair. +#include // DEDUCED_TYPENAME. +#include +#include +#include +#include +#include +#include +#include +#include // mode_of, is_direct. +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +namespace detail { + +template< typename First, + typename Second, + typename FirstMode = + BOOST_DEDUCED_TYPENAME mode_of::type, + typename SecondMode = + BOOST_DEDUCED_TYPENAME mode_of::type > +struct composite_mode + : select< + is_convertible, FirstMode, + is_convertible, SecondMode, + is_convertible, input, + else_, output + > + { }; + +// +// Template name: composite_device. +// Description: Provides a Device view of a Filter, Device pair. +// Template parameters: +// Filter - A model of Filter. +// Device - An indirect model of Device. +// +template< typename Filter, + typename Device, + typename Mode = + BOOST_DEDUCED_TYPENAME composite_mode::type > +class composite_device { +private: + typedef typename detail::param_type::type param_type; + typedef typename mode_of::type filter_mode; + typedef typename mode_of::type device_mode; + typedef typename + iostreams::select< // Disambiguation for Tru64. + is_direct, direct_adapter, + is_std_io, Device&, + else_, Device + >::type value_type; + BOOST_STATIC_ASSERT(is_filter::value); + BOOST_STATIC_ASSERT(is_device::value); +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + device_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + composite_device(const Filter& flt, param_type dev); + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ); + + void close(); + void close(BOOST_IOS::openmode which); + bool flush(); + std::streamsize optimal_buffer_size() const; + + template // Avoid dependency on + void imbue(const Locale& loc) + { + iostreams::imbue(filter_, loc); + iostreams::imbue(device_, loc); + } + + Filter& first() { return filter_; } + Device& second() { return device_; } +private: + Filter filter_; + value_type device_; +}; + +// +// Template name: composite_device. +// Description: Provides a Device view of a Filter, Device pair. +// Template parameters: +// Filter - A model of Filter. +// Device - An indirect model of Device. +// +template< typename Filter1, + typename Filter2, + typename Mode = + BOOST_DEDUCED_TYPENAME composite_mode::type > +class composite_filter { +private: + typedef reference_wrapper filter_ref; + typedef typename mode_of::type first_mode; + typedef typename mode_of::type second_mode; + + // A dual-use filter cannot be composed with a read-write filter + BOOST_STATIC_ASSERT( + !(is_convertible::value) || + !(is_convertible::value) || + !(is_convertible::value) || + (is_convertible::value) + ); + BOOST_STATIC_ASSERT( + !(is_convertible::value) || + !(is_convertible::value) || + !(is_convertible::value) || + (is_convertible::value) + ); + BOOST_STATIC_ASSERT(is_filter::value); + BOOST_STATIC_ASSERT(is_filter::value); +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + filter_tag, + multichar_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + composite_filter(const Filter1& filter1, const Filter2& filter2) + : filter1_(filter1), filter2_(filter2) + { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + composite_device cmp(boost::ref(filter2_), src); + return iostreams::read(filter1_, cmp, s, n); + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + composite_device cmp(boost::ref(filter2_), snk); + return iostreams::write(filter1_, cmp, s, n); + } + + template + std::streampos seek( Device& dev, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { + composite_device cmp(boost::ref(filter2_), dev); + return iostreams::seek(filter1_, cmp, off, way, which); + } + + template + void close(Device& dev) + { + BOOST_STATIC_ASSERT((!is_convertible::value)); + BOOST_STATIC_ASSERT((!is_convertible::value)); + + // Create a new device by composing the second filter2_ with dev. + composite_device cmp(boost::ref(filter2_), dev); + + // Close input sequences in reverse order and output sequences in + // forward order + if (!is_convertible::value) { + detail::execute_all( + detail::call_close(filter2_, dev, BOOST_IOS::in), + detail::call_close(filter1_, cmp, BOOST_IOS::in), + detail::call_close(filter1_, cmp, BOOST_IOS::out), + detail::call_close(filter2_, dev, BOOST_IOS::out) + ); + } else if (is_convertible::value) { + detail::execute_all( + detail::call_close(filter2_, dev, BOOST_IOS::in), + detail::call_close(filter1_, cmp, BOOST_IOS::in) + ); + } else { + detail::execute_all( + detail::call_close(filter1_, cmp, BOOST_IOS::out), + detail::call_close(filter2_, dev, BOOST_IOS::out) + ); + } + } + + template + void close(Device& dev, BOOST_IOS::openmode which) + { + BOOST_STATIC_ASSERT( + (is_convertible::value) || + (is_convertible::value) + ); + + // Create a new device by composing the second filter2_ with dev. + composite_device cmp(boost::ref(filter2_), dev); + + // Close input sequences in reverse order + if ( which == BOOST_IOS::in && + ( !is_convertible::value || + is_convertible::value ) ) + { + detail::execute_all( + detail::call_close(filter2_, dev, BOOST_IOS::in), + detail::call_close(filter1_, cmp, BOOST_IOS::in) + ); + } + + // Close output sequences in forward order + if ( which == BOOST_IOS::out && + ( !is_convertible::value || + is_convertible::value ) ) + { + detail::execute_all( + detail::call_close(filter1_, cmp, BOOST_IOS::out), + detail::call_close(filter2_, dev, BOOST_IOS::out) + ); + } + } + + template + bool flush(Device& dev) + { + composite_device cmp(filter2_, dev); + return iostreams::flush(filter1_, cmp); + } + + std::streamsize optimal_buffer_size() const + { + std::streamsize first = iostreams::optimal_buffer_size(filter1_); + std::streamsize second = iostreams::optimal_buffer_size(filter2_); + return first < second ? second : first; + } + + template // Avoid dependency on + void imbue(const Locale& loc) + { // To do: consider using RAII. + iostreams::imbue(filter1_, loc); + iostreams::imbue(filter2_, loc); + } + + Filter1& first() { return filter1_; } + Filter2& second() { return filter2_; } +private: + Filter1 filter1_; + Filter2 filter2_; +}; + +template +struct composite_traits + : mpl::if_< + is_device, + composite_device, + composite_filter + > + { }; + +} // End namespace detail. + +template +struct composite : detail::composite_traits::type { + typedef typename detail::param_type::type param_type; + typedef typename detail::composite_traits::type base; + composite(const Filter& flt, param_type dev) + : base(flt, dev) + { } +}; + +//--------------Implementation of compose-------------------------------------// + +// Note: The following workarounds are patterned after resolve.hpp. It has not +// yet been confirmed that they are necessary. + +#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------// +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// + +template +composite +compose( const Filter& filter, const FilterOrDevice& fod + BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) ) +{ return composite(filter, fod); } + +template +composite< Filter, std::basic_streambuf > +compose(const Filter& filter, std::basic_streambuf& sb) +{ return composite< Filter, std::basic_streambuf >(filter, sb); } + +template +composite< Filter, std::basic_istream > +compose(const Filter& filter, std::basic_istream& is) +{ return composite< Filter, std::basic_istream >(filter, is); } + +template +composite< Filter, std::basic_ostream > +compose(const Filter& filter, std::basic_ostream& os) +{ return composite< Filter, std::basic_ostream >(filter, os); } + +template +composite< Filter, std::basic_iostream > +compose(const Filter& filter, std::basic_iostream& io) +{ return composite< Filter, std::basic_iostream >(filter, io); } + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// + +template +composite +compose( const Filter& filter, const FilterOrDevice& fod + BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) ) +{ return composite(filter, fod); } + +template +composite +compose(const Filter& filter, std::streambuf& sb) +{ return composite(filter, sb); } + +template +composite +compose(const Filter& filter, std::istream& is) +{ return composite(filter, is); } + +template +composite +compose(const Filter& filter, std::ostream& os) +{ return composite(filter, os); } + +template +composite +compose(const Filter& filter, std::iostream& io) +{ return composite(filter, io); } + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// +#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------// + +template +composite +compose(const Filter& flt, const Stream& strm, mpl::true_) +{ // Bad overload resolution. + return composite(flt, const_cast(strm)); +} + +template +composite +compose(const Filter& flt, const FilterOrDevice& fod, mpl::false_) +{ return composite(flt, fod); } + +template +composite +compose( const Filter& flt, const FilterOrDevice& fod + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) +{ return compose(flt, fod, is_std_io()); } + +# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \ + !defined(__GNUC__) // ---------------------------------------------------// + +template +composite +compose (const Filter& filter, FilterOrDevice& fod) +{ return composite(filter, fod); } + +# endif // Borland 5.x or GCC //--------------------------------// +#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// + +//----------------------------------------------------------------------------// + +namespace detail { + +//--------------Implementation of composite_device---------------------------// + +template +composite_device::composite_device + (const Filter& flt, param_type dev) + : filter_(flt), device_(dev) + { } + +template +inline std::streamsize composite_device::read + (char_type* s, std::streamsize n) +{ return iostreams::read(filter_, device_, s, n); } + +template +inline std::streamsize composite_device::write + (const char_type* s, std::streamsize n) +{ return iostreams::write(filter_, device_, s, n); } + +template +std::streampos composite_device::seek + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return iostreams::seek(filter_, device_, off, way, which); } + +template +void composite_device::close() +{ + BOOST_STATIC_ASSERT((!is_convertible::value)); + BOOST_STATIC_ASSERT( + !(is_convertible::value) || + !(is_convertible::value) || + !(is_convertible::value) + ); + + // Close input sequences in reverse order and output sequences + // in forward order + if (!is_convertible::value) { + detail::execute_all( + detail::call_close(device_, BOOST_IOS::in), + detail::call_close(filter_, device_, BOOST_IOS::in), + detail::call_close(filter_, device_, BOOST_IOS::out), + detail::call_close(device_, BOOST_IOS::out) + ); + } else if (is_convertible::value) { + detail::execute_all( + detail::call_close(device_, BOOST_IOS::in), + detail::call_close(filter_, device_, BOOST_IOS::in) + ); + } else { + detail::execute_all( + detail::call_close(filter_, device_, BOOST_IOS::out), + detail::call_close(device_, BOOST_IOS::out) + ); + } +} + +template +void composite_device::close(BOOST_IOS::openmode which) +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + BOOST_STATIC_ASSERT(!(is_convertible::value)); + + // Close input sequences in reverse order + if (which == BOOST_IOS::in) { + detail::execute_all( + detail::call_close(device_, BOOST_IOS::in), + detail::call_close(filter_, device_, BOOST_IOS::in) + ); + } + + // Close output sequences in forward order + if (which == BOOST_IOS::out) { + detail::execute_all( + detail::call_close(filter_, device_, BOOST_IOS::out), + detail::call_close(device_, BOOST_IOS::out) + ); + } +} + +template +bool composite_device::flush() +{ + bool r1 = iostreams::flush(filter_, device_); + bool r2 = iostreams::flush(device_); + return r1 && r2; +} + +template +std::streamsize +composite_device::optimal_buffer_size() const +{ return iostreams::optimal_buffer_size(device_); } + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED diff --git a/boost/iostreams/concepts.hpp b/boost/iostreams/concepts.hpp new file mode 100644 index 0000000..da4bfd6 --- /dev/null +++ b/boost/iostreams/concepts.hpp @@ -0,0 +1,129 @@ +// (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 BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC +#include +#include +#include +#include // openmode. +#include +#include +#include + +namespace boost { namespace iostreams { + +//--------------Definitions of helper templates for device concepts-----------// + +template +struct device { + typedef Ch char_type; + struct category + : Mode, + device_tag, + closable_tag, + localizable_tag + { }; + + void close() + { + using namespace detail; + BOOST_STATIC_ASSERT((!is_convertible::value)); + } + + void close(BOOST_IOS::openmode) + { + using namespace detail; + BOOST_STATIC_ASSERT((is_convertible::value)); + } + + template + void imbue(const Locale&) { } +}; + +template +struct wdevice : device { }; + +typedef device source; +typedef wdevice wsource; +typedef device sink; +typedef wdevice wsink; + +//--------------Definitions of helper templates for simple filter concepts----// + +template +struct filter { + typedef Ch char_type; + struct category + : Mode, + filter_tag, + closable_tag, + localizable_tag + { }; + + template + void close(Device&) + { + using namespace detail; + BOOST_STATIC_ASSERT((!is_convertible::value)); + BOOST_STATIC_ASSERT((!is_convertible::value)); + } + + template + void close(Device&, BOOST_IOS::openmode) + { + using namespace detail; + BOOST_STATIC_ASSERT( + (is_convertible::value) || + (is_convertible::value) + ); + } + + template + void imbue(const Locale&) { } +}; + +template +struct wfilter : filter { }; + +typedef filter input_filter; +typedef wfilter input_wfilter; +typedef filter output_filter; +typedef wfilter output_wfilter; +typedef filter seekable_filter; +typedef wfilter seekable_wfilter; +typedef filter dual_use_filter; +typedef wfilter dual_use_wfilter; + +//------Definitions of helper templates for multi-character filter cncepts----// + +template +struct multichar_filter : filter { + struct category : filter::category, multichar_tag { }; +}; + +template +struct multichar_wfilter : multichar_filter { }; + +typedef multichar_filter multichar_input_filter; +typedef multichar_wfilter multichar_input_wfilter; +typedef multichar_filter multichar_output_filter; +typedef multichar_wfilter multichar_output_wfilter; +typedef multichar_filter multichar_dual_use_filter; +typedef multichar_wfilter multichar_dual_use_wfilter; + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED diff --git a/boost/iostreams/constants.hpp b/boost/iostreams/constants.hpp new file mode 100644 index 0000000..55e6f5f --- /dev/null +++ b/boost/iostreams/constants.hpp @@ -0,0 +1,42 @@ +// (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. + +// Contains constants used by library. + +#ifndef BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED +#define BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE 4096 +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE 128 +#endif + +#ifndef BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE +# define BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE 4 +#endif + +#include // streamsize. + +namespace boost { namespace iostreams { + +const std::streamsize default_device_buffer_size = + BOOST_IOSTREAMS_DEFAULT_DEVICE_BUFFER_SIZE; +const std::streamsize default_filter_buffer_size = + BOOST_IOSTREAMS_DEFAULT_FILTER_BUFFER_SIZE; +const std::streamsize default_pback_buffer_size = + BOOST_IOSTREAMS_DEFAULT_PBACK_BUFFER_SIZE; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_CONSTANTS_HPP_INCLUDED diff --git a/boost/iostreams/copy.hpp b/boost/iostreams/copy.hpp new file mode 100644 index 0000000..3579a9c --- /dev/null +++ b/boost/iostreams/copy.hpp @@ -0,0 +1,248 @@ +// (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. + +// Contains: The function template copy, which reads data from a Source +// and writes it to a Sink until the end of the sequence is reached, returning +// the number of characters transfered. + +// The implementation is complicated by the need to handle smart adapters +// and direct devices. + +#ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED +#define BOOST_IOSTREAMS_COPY_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // Make sure ptrdiff_t is in std. +#include // copy, min. +#include // ptrdiff_t. +#include // pair. + +#include +#include +#include +#include +#include +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include // read, write, close. +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + + // The following four overloads of copy_impl() optimize + // copying in the case that one or both of the two devices + // models Direct (see + // http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4) + +// Copy from a direct source to a direct sink +template +std::streamsize copy_impl( Source& src, Sink& snk, + std::streamsize /* buffer_size */, + mpl::true_, mpl::true_ ) +{ + using namespace std; + typedef typename char_type_of::type char_type; + typedef std::pair pair_type; + pair_type p1 = iostreams::input_sequence(src); + pair_type p2 = iostreams::output_sequence(snk); + std::streamsize total = + static_cast( + (std::min)(p1.second - p1.first, p2.second - p2.first) + ); + std::copy(p1.first, p1.first + total, p2.first); + return total; +} + +// Copy from a direct source to an indirect sink +template +std::streamsize copy_impl( Source& src, Sink& snk, + std::streamsize /* buffer_size */, + mpl::true_, mpl::false_ ) +{ + using namespace std; + typedef typename char_type_of::type char_type; + typedef std::pair pair_type; + pair_type p = iostreams::input_sequence(src); + std::streamsize size, total; + for ( total = 0, size = static_cast(p.second - p.first); + total < size; ) + { + std::streamsize amt = + iostreams::write(snk, p.first + total, size - total); + total += amt; + } + return total; +} + +// Copy from an indirect source to a direct sink +template +std::streamsize copy_impl( Source& src, Sink& snk, + std::streamsize buffer_size, + mpl::false_, mpl::true_ ) +{ + typedef typename char_type_of::type char_type; + typedef std::pair pair_type; + detail::basic_buffer buf(buffer_size); + pair_type p = snk.output_sequence(); + std::streamsize total = 0; + std::ptrdiff_t capacity = p.second - p.first; + while (true) { + std::streamsize amt = + iostreams::read( + src, + buf.data(), + buffer_size < capacity - total ? + buffer_size : + static_cast(capacity - total) + ); + if (amt == -1) + break; + std::copy(buf.data(), buf.data() + amt, p.first + total); + total += amt; + } + return total; +} + +// Copy from an indirect source to an indirect sink +template +std::streamsize copy_impl( Source& src, Sink& snk, + std::streamsize buffer_size, + mpl::false_, mpl::false_ ) +{ + typedef typename char_type_of::type char_type; + detail::basic_buffer buf(buffer_size); + non_blocking_adapter nb(snk); + std::streamsize total = 0; + bool done = false; + while (!done) { + std::streamsize amt; + done = (amt = iostreams::read(src, buf.data(), buffer_size)) == -1; + if (amt != -1) { + iostreams::write(nb, buf.data(), amt); + total += amt; + } + } + return total; +} + + // The following function object is used with + // boost::iostreams::detail::execute() in the primary + // overload of copy_impl(), below + +// Function object that delegates to one of the above four +// overloads of compl_impl() +template +class copy_operation { +public: + typedef std::streamsize result_type; + copy_operation(Source& src, Sink& snk, std::streamsize buffer_size) + : src_(src), snk_(snk), buffer_size_(buffer_size) + { } + std::streamsize operator()() + { + return copy_impl( src_, snk_, buffer_size_, + is_direct(), is_direct() ); + } +private: + copy_operation& operator=(const copy_operation&); + Source& src_; + Sink& snk_; + std::streamsize buffer_size_; +}; + +// Primary overload of copy_impl. Delegates to one of the above four +// overloads of compl_impl(), depending on which of the two given +// devices, if any, models Direct (see +// http://www.boost.org/libs/iostreams/doc/index.html?path=4.1.1.4) +template +std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size) +{ + using namespace std; + typedef typename char_type_of::type src_char; + typedef typename char_type_of::type snk_char; + BOOST_STATIC_ASSERT((is_same::value)); + return detail::execute_all( + copy_operation(src, snk, buffer_size), + detail::call_close_all(src), + detail::call_close_all(snk) + ); +} + +} // End namespace detail. + +//------------------Definition of copy----------------------------------------// + +// Overload of copy() for the case where neither the source nor the sink is +// a standard stream or stream buffer +template +std::streamsize +copy( const Source& src, const Sink& snk, + std::streamsize buffer_size = default_device_buffer_size + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source) + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) +{ + typedef typename char_type_of::type char_type; + return detail::copy_impl( detail::resolve(src), + detail::resolve(snk), + buffer_size ); +} + +// Overload of copy() for the case where the source, but not the sink, is +// a standard stream or stream buffer +template +std::streamsize +copy( Source& src, const Sink& snk, + std::streamsize buffer_size = default_device_buffer_size + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source) + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Sink) ) +{ + typedef typename char_type_of::type char_type; + return detail::copy_impl( detail::wrap(src), + detail::resolve(snk), + buffer_size ); +} + +// Overload of copy() for the case where the sink, but not the source, is +// a standard stream or stream buffer +template +std::streamsize +copy( const Source& src, Sink& snk, + std::streamsize buffer_size = default_device_buffer_size + BOOST_IOSTREAMS_DISABLE_IF_STREAM(Source) + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) +{ + typedef typename char_type_of::type char_type; + return detail::copy_impl( detail::resolve(src), + detail::wrap(snk), buffer_size ); +} + +// Overload of copy() for the case where neither the source nor the sink is +// a standard stream or stream buffer +template +std::streamsize +copy( Source& src, Sink& snk, + std::streamsize buffer_size = default_device_buffer_size + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Source) + BOOST_IOSTREAMS_ENABLE_IF_STREAM(Sink) ) +{ + return detail::copy_impl(detail::wrap(src), detail::wrap(snk), buffer_size); +} + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_COPY_HPP_INCLUDED diff --git a/boost/iostreams/detail/absolute_path.hpp b/boost/iostreams/detail/absolute_path.hpp new file mode 100644 index 0000000..090958a --- /dev/null +++ b/boost/iostreams/detail/absolute_path.hpp @@ -0,0 +1,46 @@ +/* + * 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. + + * File: boost/iostreams/detail/execute.hpp + * Date: Thu Dec 06 13:21:54 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the function boost::iostreams::detail::absolute_path, used for + * debug output for mapped files. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED + +#include +#include +#ifdef BOOST_IOSTREAMS_WINDOWS +# include +#endif +#include + +namespace boost { namespace iostreams { namespace detail { + +// Resolves the given path relative to the current working directory +inline std::string absolute_path(const std::string& path) +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + return path.size() && (path[0] == '/' || path[0] == '\\') || + path.size() > 1 && std::isalpha(path[0]) && path[1] == ':' ? + path : + current_directory() + '\\' + path; +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + return path.size() && (path[0] == '/') ? + path : + current_directory() + '/' + path; +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ABSOLUTE_PATH_HPP_INCLUDED diff --git a/boost/iostreams/detail/access_control.hpp b/boost/iostreams/detail/access_control.hpp new file mode 100644 index 0000000..9c3328a --- /dev/null +++ b/boost/iostreams/detail/access_control.hpp @@ -0,0 +1,87 @@ +// (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. + +// Contains the definition of the class template access_control, which +// allows the type of inheritance from a provided base class to be specified +// using a template parameter. + + +#ifndef BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED +#define BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include + +namespace boost { namespace iostreams { + +struct protected_ { }; // Represents protected inheritance. +struct public_ { }; // Represents public inheritance. + + +namespace detail { + + // Implements protected inheritance. + template + struct prot_ : protected U + { + prot_() { } + template prot_(V v) : U(v) { } + }; + + // Implements public inheritance. + template struct pub_ : public U { + pub_() { } + template pub_(V v) : U(v) { } + }; + +// +// Used to deduce the base type for the template access_control. +// +template +struct access_control_base { + typedef int bad_access_specifier; + typedef typename + iostreams::select< // Disambiguation for Tru64 + ::boost::is_same< + Access, protected_ + >, prot_, + ::boost::is_same< + Access, public_ + >, pub_, + else_, bad_access_specifier + >::type type; +}; + +} // End namespace detail. + +// +// Template name: access_control. +// Description: Allows the type of inheritance from a provided base class +// to be specified using an int template parameter. +// Template parameters: +// Base - The class from which to inherit (indirectly.) +// Access - The type of access desired. Must be one of the +// values access_base::prot or access_base::pub. +// +template< typename T, typename Access, + typename Base = // VC6 workaraound (Compiler Error C2516) + typename detail::access_control_base::type > +struct access_control : public Base { + access_control() { } + template explicit access_control(U u) : Base(u) { } +}; + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/concept_adapter.hpp b/boost/iostreams/detail/adapter/concept_adapter.hpp new file mode 100644 index 0000000..69a9115 --- /dev/null +++ b/boost/iostreams/detail/adapter/concept_adapter.hpp @@ -0,0 +1,287 @@ +// (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 BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED + +#include // SFINAE. +#include +#include +#include +#include +#include +#include +#include +#include // pubsync. +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + + +namespace boost { namespace iostreams { namespace detail { + +template struct device_wrapper_impl; +template struct flt_wrapper_impl; + +template +class concept_adapter { +private: + typedef typename detail::value_type::type value_type; + typedef typename dispatch::type input_tag; + typedef typename dispatch::type output_tag; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type input_impl; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type output_impl; + typedef typename + mpl::if_< + is_device, + device_wrapper_impl, + flt_wrapper_impl + >::type any_impl; +public: + typedef typename char_type_of::type char_type; + typedef typename category_of::type category; + + explicit concept_adapter(const reference_wrapper& ref) : t_(ref.get()) + { BOOST_STATIC_ASSERT(is_std_io::value); } + explicit concept_adapter(const T& t) : t_(t) + { BOOST_STATIC_ASSERT(!is_std_io::value); } + + T& operator*() { return t_; } + T* operator->() { return &t_; } + + std::streamsize read(char_type* s, std::streamsize n) + { return this->read(s, n, (basic_null_source*) 0); } + + template + std::streamsize read(char_type* s, std::streamsize n, Source* src) + { return input_impl::read(t_, src, s, n); } + + std::streamsize write(const char_type* s, std::streamsize n) + { return this->write(s, n, (basic_null_sink*) 0); } + + template + std::streamsize write(const char_type* s, std::streamsize n, Sink* snk) + { return output_impl::write(t_, snk, s, n); } + + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + return this->seek( off, way, which, + (basic_null_device*) 0); + } + + template + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which, Device* dev ) + { return any_impl::seek(t_, dev, off, way, which); } + + void close(BOOST_IOS::openmode which) + { this->close(which, (basic_null_device*) 0); } + + template + void close(BOOST_IOS::openmode which, Device* dev) + { any_impl::close(t_, dev, which); } + + template + bool flush( Device* dev ) + { + bool result = any_impl::flush(t_, dev); + if (dev && dev->BOOST_IOSTREAMS_PUBSYNC() == -1) + result = false; + return result; + } + + 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_); } +private: + BOOST_DELETED_FUNCTION(concept_adapter& operator=(const concept_adapter&)) + value_type t_; +}; + +//------------------Specializations of device_wrapper_impl--------------------// + +template<> +struct device_wrapper_impl { + template + static std::streampos + seek( Device& dev, Dummy*, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { + typedef typename category_of::type category; + return seek(dev, off, way, which, category()); + } + + template + static std::streampos + seek( Device&, stream_offset, BOOST_IOS::seekdir, + BOOST_IOS::openmode, any_tag ) + { + boost::throw_exception(cant_seek()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) + } + + template + static std::streampos + seek( Device& dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access ) + { + return iostreams::seek(dev, off, way, which); + } + + template + static void close(Device& dev, Dummy*, BOOST_IOS::openmode which) + { iostreams::close(dev, which); } + + template + static bool flush(Device& dev, Dummy*) + { return iostreams::flush(dev); } +}; + + +template<> +struct device_wrapper_impl : device_wrapper_impl { + template + static std::streamsize + read( Device& dev, Dummy*, typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::read(dev, s, n); } + + template + static std::streamsize + write( Device&, Dummy*, const typename char_type_of::type*, + std::streamsize ) + { boost::throw_exception(cant_write()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } +}; + +template<> +struct device_wrapper_impl { + template + static std::streamsize + read(Device&, Dummy*, typename char_type_of::type*, std::streamsize) + { boost::throw_exception(cant_read()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } + + template + static std::streamsize + write( Device& dev, Dummy*, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(dev, s, n); } +}; + +//------------------Specializations of flt_wrapper_impl--------------------// + +template<> +struct flt_wrapper_impl { + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { + typedef typename category_of::type category; + return seek(f, dev, off, way, which, category()); + } + + template + static std::streampos + seek( Filter&, Device*, stream_offset, + BOOST_IOS::seekdir, BOOST_IOS::openmode, any_tag ) + { boost::throw_exception(cant_seek()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access tag ) + { + typedef typename category_of::type category; + return seek(f, dev, off, way, which, tag, category()); + } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode, + random_access, any_tag ) + { return f.seek(*dev, off, way); } + + template + static std::streampos + seek( Filter& f, Device* dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which, + random_access, two_sequence ) + { return f.seek(*dev, off, way, which); } + + template + static void close(Filter& f, Device* dev, BOOST_IOS::openmode which) + { iostreams::close(f, *dev, which); } + + template + static bool flush(Filter& f, Device* dev) + { return iostreams::flush(f, *dev); } +}; + +template<> +struct flt_wrapper_impl { + template + static std::streamsize + read( Filter& f, Source* src, typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::read(f, *src, s, n); } + + template + static std::streamsize + write( Filter&, Sink*, const typename char_type_of::type*, + std::streamsize ) + { boost::throw_exception(cant_write()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } +}; + +template<> +struct flt_wrapper_impl { + template + static std::streamsize + read(Filter&, Source*, typename char_type_of::type*,std::streamsize) + { boost::throw_exception(cant_read()); + BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) } + + template + static std::streamsize + write( Filter& f, Sink* snk, const typename char_type_of::type* s, + std::streamsize n ) + { return iostreams::write(f, *snk, s, n); } +}; + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/device_adapter.hpp b/boost/iostreams/detail/adapter/device_adapter.hpp new file mode 100644 index 0000000..9dd723a --- /dev/null +++ b/boost/iostreams/detail/adapter/device_adapter.hpp @@ -0,0 +1,67 @@ +/* + * Defines the class template boost::iostreams::detail::device_adapter, + * a convenience base class for device adapters. + * + * File: boost/iostreams/detail/adapter/filter_adapter.hpp + * Date: Mon Nov 26 14:35:48 MST 2007 + * + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * 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_DEVICE_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DEVICE_ADAPTER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class device_adapter { +private: + typedef typename detail::value_type::type value_type; + typedef typename detail::param_type::type param_type; +public: + explicit device_adapter(param_type t) : t_(t) { } + T& component() { return t_; } + + void close() + { + detail::close_all(t_); + } + + void close(BOOST_IOS::openmode which) + { + iostreams::close(t_, which); + } + + bool flush() + { + return iostreams::flush(t_); + } + + 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_DEVICE_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/direct_adapter.hpp b/boost/iostreams/detail/adapter/direct_adapter.hpp new file mode 100644 index 0000000..60fe8c2 --- /dev/null +++ b/boost/iostreams/detail/adapter/direct_adapter.hpp @@ -0,0 +1,282 @@ +// (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 BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // SFINAE, MSVC, put ptrdiff_t in std. +#include // copy, min. +#include // ptrdiff_t. +#include +#include +#include // forwarding. +#include // locale. +#include +#include +#include // openmode, seekdir, int types. +#include // mode_of, is_direct. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // VC7.1 + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of direct_adapter_base-------------------------// + +// Put all initialization in base class to faciliate forwarding. +template +class direct_adapter_base { +public: + typedef typename char_type_of::type char_type; + typedef typename mode_of::type mode_type; + struct category + : mode_type, + device_tag, + closable_tag + #ifndef BOOST_IOSTREAMS_NO_LOCALE + , localizable_tag + #endif + { }; +protected: + explicit direct_adapter_base(const Direct& d); + typedef is_convertible is_double; + struct pointers { + pointers() : beg(0), ptr(0), end(0) { } + char_type *beg, *ptr, *end; + }; + void init_input(mpl::true_); + void init_input(mpl::false_) { } + void init_output(mpl::true_); + void init_output(mpl::false_) { } + double_object ptrs_; + Direct d_; +}; + +template +class direct_adapter : private direct_adapter_base { +private: + typedef direct_adapter_base base_type; + typedef typename base_type::pointers pointers; + typedef typename base_type::is_double is_double; + using base_type::ptrs_; + using base_type::d_; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + + // Constructors + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1310) + direct_adapter(const Direct& d) : base_type(d) { } + direct_adapter(const direct_adapter& d) : base_type(d) { } +# define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) +#else + template + struct is_direct + : mpl::or_< + is_same >, + is_same + > + { }; + template + direct_adapter(const U& u) + : base_type(forward(u, is_direct())) + { } +# define BOOST_PP_LOCAL_LIMITS (2, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) +#endif + +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + direct_adapter(BOOST_PP_ENUM_BINARY_PARAMS(n, const P, &p)) \ + : base_type(Direct(BOOST_PP_ENUM_PARAMS(n, p))) \ + { } \ + /**/ +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO + + // Device interface. + + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek( stream_offset, BOOST_IOS::seekdir, + BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out ); + void close(); + void close(BOOST_IOS::openmode which); +#ifndef BOOST_IOSTREAMS_NO_LOCALE + void imbue(const std::locale&); +#endif + + // Direct device access. + + Direct& operator*() { return d_; } + Direct* operator->() { return &d_; } +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) +private: + template + static Direct forward(const U& u, mpl::true_) { return u; } + template + static Direct forward(const U& u, mpl::false_) { return Direct(u); } +#endif +}; + +//--------------Definition of wrap_direct and unwrap_direct-------------------// + +template +struct wrap_direct_traits + : mpl::if_< + is_direct, + direct_adapter, + Device + > + { }; + +template +typename wrap_direct_traits::type +inline wrap_direct(Device dev) +{ + typedef typename wrap_direct_traits::type type; + return type(dev); +} + +template +inline Device& unwrap_direct(Device& d) { return d; } + +template +inline Device& unwrap_direct(direct_adapter& d) { return *d; } + +//--------------Implementation of direct_adapter_base-------------------------// + +template +direct_adapter_base::direct_adapter_base(const Direct& d) : d_(d) +{ + init_input(is_convertible()); + init_output(is_convertible()); +} + +template +void direct_adapter_base::init_input(mpl::true_) +{ + std::pair seq = iostreams::input_sequence(d_); + ptrs_.first().beg = seq.first; + ptrs_.first().ptr = seq.first; + ptrs_.first().end = seq.second; +} + +template +void direct_adapter_base::init_output(mpl::true_) +{ + std::pair seq = iostreams::output_sequence(d_); + ptrs_.second().beg = seq.first; + ptrs_.second().ptr = seq.first; + ptrs_.second().end = seq.second; +} + +//--------------Implementation of direct_adapter------------------------------// + +template +inline std::streamsize direct_adapter::read + (char_type* s, std::streamsize n) +{ + using namespace std; + pointers& get = ptrs_.first(); + std::streamsize avail = + static_cast(get.end - get.ptr); + std::streamsize result = (std::min)(n, avail); + std::copy(get.ptr, get.ptr + result, s); + get.ptr += result; + return result != 0 ? result : -1; +} + +template +inline std::streamsize direct_adapter::write + (const char_type* s, std::streamsize n) +{ + using namespace std; + pointers& put = ptrs_.second(); + if (n > static_cast(put.end - put.ptr)) + boost::throw_exception(write_area_exhausted()); + std::copy(s, s + n, put.ptr); + put.ptr += n; + return n; +} + +template +inline std::streampos direct_adapter::seek + ( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) +{ + using namespace std; + pointers& get = ptrs_.first(); + pointers& put = ptrs_.second(); + if (way == BOOST_IOS::cur && get.ptr != put.ptr) + boost::throw_exception(bad_seek()); + ptrdiff_t next = 0; + if ((which & BOOST_IOS::in) || !is_double::value) { + if (way == BOOST_IOS::beg) + next = off; + else if (way == BOOST_IOS::cur) + next = get.ptr - get.beg + off; + else + next = get.end - get.beg + off; + if (next >= 0 && next <= get.end - get.beg) + get.ptr = get.beg + next; + else + boost::throw_exception(bad_seek()); + } + if ((which & BOOST_IOS::out) && is_double::value) { + if (way == BOOST_IOS::beg) + next = off; + else if (way == BOOST_IOS::cur) + next = put.ptr - put.beg + off; + else + next = put.end - put.beg + off; + if (next >= 0 && next <= put.end - put.beg) + put.ptr = put.beg + next; + else + boost::throw_exception(bad_seek()); + } + return offset_to_position(next); +} + +template +void direct_adapter::close() +{ + BOOST_STATIC_ASSERT((!is_convertible::value)); + detail::close_all(d_); +} + +template +void direct_adapter::close(BOOST_IOS::openmode which) +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + boost::iostreams::close(d_, which); +} + +#ifndef BOOST_IOSTREAMS_NO_LOCALE + template + void direct_adapter::imbue(const std::locale& loc) + { boost::iostreams::imbue(d_, loc); } +#endif + +} } } // End namespaces detail, iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/filter_adapter.hpp b/boost/iostreams/detail/adapter/filter_adapter.hpp new file mode 100644 index 0000000..a2ab492 --- /dev/null +++ b/boost/iostreams/detail/adapter/filter_adapter.hpp @@ -0,0 +1,69 @@ +/* + * Defines the class template boost::iostreams::detail::filter_adapter, + * a convenience base class for filter adapters. + * + * File: boost/iostreams/detail/adapter/filter_adapter.hpp + * Date: Mon Nov 26 14:35:48 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * 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_FILTER_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FILTER_ADAPTER_HPP_INCLUDED + +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class filter_adapter { +private: + typedef typename detail::value_type::type value_type; + typedef typename detail::param_type::type param_type; +public: + explicit filter_adapter(param_type t) : t_(t) { } + T& component() { return t_; } + + template + void close(Device& dev) + { + detail::close_all(t_, dev); + } + + template + void close(Device& dev, BOOST_IOS::openmode which) + { + iostreams::close(t_, dev, which); + } + + template + void flush(Device& dev) + { + 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_FILTER_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/mode_adapter.hpp b/boost/iostreams/detail/adapter/mode_adapter.hpp new file mode 100644 index 0000000..46e83c5 --- /dev/null +++ b/boost/iostreams/detail/adapter/mode_adapter.hpp @@ -0,0 +1,117 @@ +// (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 BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +// Contains the definition of the class template mode_adapter, which allows +// a filter or device to function as if it has a different i/o mode than that +// deduced by the metafunction mode_of. + +#include // BOOST_MSVC. +#include +#include +#include // openmode, seekdir, int types. +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class mode_adapter { +private: + struct empty_base { }; +public: + typedef typename wrapped_type::type component_type; + typedef typename char_type_of::type char_type; + struct category + : Mode, + device_tag, + mpl::if_, filter_tag, device_tag>, + mpl::if_, multichar_tag, empty_base>, + closable_tag, + localizable_tag + { }; + explicit mode_adapter(const component_type& t) : t_(t) { } + + // Device member functions. + + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ); + void close(); + void close(BOOST_IOS::openmode which); + + // Filter member functions. + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { return iostreams::read(t_, src, s, n); } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { return iostreams::write(t_, snk, s, n); } + + template + std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way) + { return iostreams::seek(t_, dev, off, way); } + + template + std::streampos seek( Device& dev, stream_offset off, + BOOST_IOS::seekdir way, BOOST_IOS::openmode which ) + { return iostreams::seek(t_, dev, off, way, which); } + + template + void close(Device& dev) + { detail::close_all(t_, dev); } + + template + void close(Device& dev, BOOST_IOS::openmode which) + { iostreams::close(t_, dev, which); } + + template + void imbue(const Locale& loc) + { iostreams::imbue(t_, loc); } +private: + component_type t_; +}; + +//------------------Implementation of mode_adapter----------------------------// + +template +std::streamsize mode_adapter::read + (char_type* s, std::streamsize n) +{ return boost::iostreams::read(t_, s, n); } + +template +std::streamsize mode_adapter::write + (const char_type* s, std::streamsize n) +{ return boost::iostreams::write(t_, s, n); } + +template +std::streampos mode_adapter::seek + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return boost::iostreams::seek(t_, off, way, which); } + +template +void mode_adapter::close() +{ detail::close_all(t_); } + +template +void mode_adapter::close(BOOST_IOS::openmode which) +{ iostreams::close(t_, which); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED //-----// diff --git a/boost/iostreams/detail/adapter/non_blocking_adapter.hpp b/boost/iostreams/detail/adapter/non_blocking_adapter.hpp new file mode 100644 index 0000000..85794d0 --- /dev/null +++ b/boost/iostreams/detail/adapter/non_blocking_adapter.hpp @@ -0,0 +1,62 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED + +#include // streamsize, seekdir, openmode. +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +template +class non_blocking_adapter { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, device_tag + { }; + explicit non_blocking_adapter(Device& dev) : device_(dev) { } + std::streamsize read(char_type* s, std::streamsize n) + { + std::streamsize result = 0; + while (result < n) { + std::streamsize amt = iostreams::read(device_, s + result, n - result); + if (amt == -1) + break; + result += amt; + } + return result != 0 ? result : -1; + } + std::streamsize write(const char_type* s, std::streamsize n) + { + std::streamsize result = 0; + while (result < n) { + std::streamsize amt = + iostreams::write(device_, s + result, n - result); + // write errors, like EOF on read, need to be handled. + if (amt == -1) + break; + result += amt; + } + return result; + } + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { return iostreams::seek(device_, off, way, which); } +public: + non_blocking_adapter& operator=(const non_blocking_adapter&); + Device& device_; +}; + +} } // End namespace iostreams. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_NON_BLOCKING_ADAPTER_HPP_INCLUDED diff --git a/boost/iostreams/detail/adapter/output_iterator_adapter.hpp b/boost/iostreams/detail/adapter/output_iterator_adapter.hpp new file mode 100644 index 0000000..2ed9039 --- /dev/null +++ b/boost/iostreams/detail/adapter/output_iterator_adapter.hpp @@ -0,0 +1,41 @@ +// (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 BOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // copy. +#include // streamsize. +#include // tags. +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +class output_iterator_adapter { +public: + BOOST_STATIC_ASSERT((is_convertible::value)); + typedef Ch char_type; + typedef sink_tag category; + explicit output_iterator_adapter(OutIt out) : out_(out) { } + std::streamsize write(const char_type* s, std::streamsize n) + { + std::copy(s, s + n, out_); + return n; + } +private: + OutIt out_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_OUTPUT_ITERATOR_ADAPTER_HPP_INCLUDED //-----// diff --git a/boost/iostreams/detail/adapter/range_adapter.hpp b/boost/iostreams/detail/adapter/range_adapter.hpp new file mode 100644 index 0000000..fa152f6 --- /dev/null +++ b/boost/iostreams/detail/adapter/range_adapter.hpp @@ -0,0 +1,187 @@ +// (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 BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // min. +#include +#include // ptrdiff_t. +#include // streamsize, streamoff. +#include // iterator_traits. +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +// Used for simulated tag dispatch. +template struct range_adapter_impl; + +// +// Template name: range_adapter +// Description: Device based on an instance of boost::iterator_range. +// Template parameters: +// Mode - A mode tag. +// Range - An instance of iterator_range. +// +template +class range_adapter { +private: + typedef typename Range::iterator iterator; + typedef std::iterator_traits iter_traits; + typedef typename iter_traits::iterator_category iter_cat; +public: + typedef typename Range::value_type char_type; + struct category : Mode, device_tag { }; + typedef typename + mpl::if_< + is_convertible< + iter_cat, + std::random_access_iterator_tag + >, + std::random_access_iterator_tag, + std::forward_iterator_tag + >::type tag; + typedef range_adapter_impl impl; + + explicit range_adapter(const Range& rng); + range_adapter(iterator first, iterator last); + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); +private: + iterator first_, cur_, last_; +}; + +//------------------Implementation of range_adapter---------------------------// + +template +range_adapter::range_adapter(const Range& rng) + : first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { } + +template +range_adapter::range_adapter(iterator first, iterator last) + : first_(first), cur_(first), last_(last) { } + +template +inline std::streamsize range_adapter::read + (char_type* s, std::streamsize n) +{ return impl::read(cur_, last_, s, n); } + +template +inline std::streamsize range_adapter::write + (const char_type* s, std::streamsize n) +{ return impl::write(cur_, last_, s, n); } + + +template +std::streampos range_adapter::seek + (stream_offset off, BOOST_IOS::seekdir way) +{ + impl::seek(first_, cur_, last_, off, way); + return offset_to_position(cur_ - first_); +} + +//------------------Implementation of range_adapter_impl----------------------// + +template<> +struct range_adapter_impl { + template + static std::streamsize read + (Iter& cur, Iter& last, Ch* s,std::streamsize n) + { + std::streamsize rem = n; // No. of chars remaining. + while (cur != last && rem-- > 0) *s++ = *cur++; + return n - rem != 0 ? n - rem : -1; + } + + template + static std::streamsize write + (Iter& cur, Iter& last, const Ch* s, std::streamsize n) + { + while (cur != last && n-- > 0) *cur++ = *s++; + if (cur == last && n > 0) + boost::throw_exception(write_area_exhausted()); + return n; + } +}; + +template<> +struct range_adapter_impl { + template + static std::streamsize read + (Iter& cur, Iter& last, Ch* s,std::streamsize n) + { + std::streamsize result = + (std::min)(static_cast(last - cur), n); + if (result) + std::copy(cur, cur + result, s); + cur += result; + return result != 0 ? result : -1; + } + + template + static std::streamsize write + (Iter& cur, Iter& last, const Ch* s, std::streamsize n) + { + std::streamsize count = + (std::min)(static_cast(last - cur), n); + std::copy(s, s + count, cur); + cur += count; + if (count < n) + boost::throw_exception(write_area_exhausted()); + return n; + } + + template + static void seek + ( Iter& first, Iter& cur, Iter& last, stream_offset off, + BOOST_IOS::seekdir way ) + { + using namespace std; + switch (way) { + case BOOST_IOS::beg: + if (off > last - first || off < 0) + boost::throw_exception(bad_seek()); + cur = first + off; + break; + case BOOST_IOS::cur: + { + std::ptrdiff_t newoff = cur - first + off; + if (newoff > last - first || newoff < 0) + boost::throw_exception(bad_seek()); + cur += off; + break; + } + case BOOST_IOS::end: + if (last - first + off < 0 || off > 0) + boost::throw_exception(bad_seek()); + cur = last + off; + break; + default: + BOOST_ASSERT(0); + } + } +}; + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------// diff --git a/boost/iostreams/detail/add_facet.hpp b/boost/iostreams/detail/add_facet.hpp new file mode 100644 index 0000000..6033d4f --- /dev/null +++ b/boost/iostreams/detail/add_facet.hpp @@ -0,0 +1,49 @@ +// (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. + +// Borrowed from + +#ifndef BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_DINKUMWARE_STDLIB. +#include + +//------------------Definition of add_facet-----------------------------------// + +// Does STLport uses old Dinkumware locale? +#if (defined(__SGI_STL_PORT) || defined(_STLPORT_VERSION)) && \ + defined(_STLP_NO_OWN_IOSTREAMS) \ + /**/ +# if (defined(_YVALS) && !defined(__IBMCPP__)) || defined(_CPPLIB_VER) +# define BOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE +# endif +#endif + +namespace boost { namespace iostreams { namespace detail { + +template +inline std::locale add_facet(const std::locale &l, Facet * f) +{ + return + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) || \ + defined(BOOST_IOSTREMS_STLPORT_WITH_OLD_DINKUMWARE) \ + /**/ + std::locale(std::_Addfac(l, f)); + #else + // standard compatible + std::locale(l, f); + #endif +} + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ADD_FACET_HPP_INCLUDED diff --git a/boost/iostreams/detail/bool_trait_def.hpp b/boost/iostreams/detail/bool_trait_def.hpp new file mode 100644 index 0000000..758e1cc --- /dev/null +++ b/boost/iostreams/detail/bool_trait_def.hpp @@ -0,0 +1,49 @@ +// (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 BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED + +#include // BOOST_STATIC_CONSTANT. +#include +#include +#include +#include +#include +#include + +// +// Macro name: BOOST_IOSTREAMS_BOOL_TRAIT_DEF +// Description: Used to generate the traits classes is_istream, is_ostream, +// etc. +// +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x582)) +# define BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) +#else +# define BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) BOOST_PP_CAT(trait, _impl_):: +#endif +#define BOOST_IOSTREAMS_BOOL_TRAIT_DEF(trait, type, arity) \ + namespace BOOST_PP_CAT(trait, _impl_) { \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, T) \ + type_traits::yes_type helper \ + (const volatile type BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)*); \ + type_traits::no_type helper(...); \ + template \ + struct impl { \ + BOOST_STATIC_CONSTANT(bool, value = \ + (sizeof(BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) \ + helper(static_cast(0))) == \ + sizeof(type_traits::yes_type))); \ + }; \ + } \ + template \ + struct trait \ + : mpl::bool_::value> \ + { BOOST_MPL_AUX_LAMBDA_SUPPORT(1, trait, (T)) }; \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED diff --git a/boost/iostreams/detail/broken_overload_resolution/forward.hpp b/boost/iostreams/detail/broken_overload_resolution/forward.hpp new file mode 100644 index 0000000..4444916 --- /dev/null +++ b/boost/iostreams/detail/broken_overload_resolution/forward.hpp @@ -0,0 +1,31 @@ +// (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 BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED + +#include // BOOST_STATIC_CONSANT. +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct forward_impl { + BOOST_STATIC_CONSTANT(bool, value = + ( !is_same< U, Device >::value && + !is_same< U, reference_wrapper >::value )); +}; + +template +struct forward + : mpl::bool_::value> + { }; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED diff --git a/boost/iostreams/detail/broken_overload_resolution/stream.hpp b/boost/iostreams/detail/broken_overload_resolution/stream.hpp new file mode 100644 index 0000000..834f996 --- /dev/null +++ b/boost/iostreams/detail/broken_overload_resolution/stream.hpp @@ -0,0 +1,184 @@ +// (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 BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED + +#include + +namespace boost { namespace iostreams { + +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +struct stream : detail::stream_base { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, + closable_tag, + detail::stream_traits::stream_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename + detail::stream_traits< + Device, Tr + >::stream_type stream_type; +public: + stream() { } + template + stream(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + stream(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + bool is_open() const { return this->member.is_open(); } + void close() { this->member.close(); } + bool auto_close() const { return this->member.auto_close(); } + void set_auto_close(bool close) { this->member.set_auto_close(close); } + bool strict_sync() { return this->member.strict_sync(); } + Device& operator*() { return *this->member; } + Device* operator->() { return &*this->member; } +private: + template + void open_impl(mpl::false_, const U0& u0) + { + this->clear(); + this->member.open(u0); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::false_, U0& u0) + { + this->clear(); + this->member.open(detail::wrap(u0)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::true_, const U0& u0) + { + this->clear(); + this->member.open(Device(const_cast(u0))); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0) + { + this->clear(); + this->member.open(Device(u0)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1) + { + this->clear(); + this->member.open(u0, u1); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1) + { + this->clear(); + this->member.open(Device(const_cast(u0), u1)); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1) + { + this->clear(); + this->member.open(Device(u0, u1)); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(u0, u1, u2); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(Device(const_cast(u0), u1, u2)); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2) + { + this->clear(); + this->member.open(Device(u0, u1, u2)); + } +#endif +}; + +} } // End namespaces iostreams, boost. + +#endif BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_HPP_INCLUDED diff --git a/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp b/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp new file mode 100644 index 0000000..d5c7107 --- /dev/null +++ b/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp @@ -0,0 +1,189 @@ +// (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 BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED + +#include +#include + +namespace boost { namespace iostreams { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Mode = BOOST_DEDUCED_TYPENAME mode_of::type > +class stream_buffer + : public detail::stream_buffer_traits::type +{ +private: + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, Mode + >::value + )); + typedef typename + detail::stream_buffer_traits< + T, Tr, Alloc, Mode + >::type base_type; +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + closable_tag, + streambuf_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) + stream_buffer() { } + ~stream_buffer() + { + try { + if (this->is_open() && this->auto_close()) + this->close(); + } catch (...) { } + } + template + stream_buffer(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream_buffer(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream_buffer(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + stream_buffer(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + stream_buffer(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + stream_buffer(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open(const U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(const U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(const U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open(U0& u0) + { + open_impl(detail::forward(), u0); + } + template + void open(U0& u0, const U1& u1) + { + open_impl(detail::forward(), u0, u1); + } + template + void open(U0& u0, const U1& u1, const U2& u2) + { + open_impl(detail::forward(), u0, u1, u2); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + T& operator*() { return *this->component(); } + T* operator->() { return this->component(); } +private: + template + void open_impl(mpl::false_, const U0& u0) + { + base_type::open(const_cast(u0), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::false_, U0& u0) + { + base_type::open(detail::wrap(u0), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::true_, const U0& u0) + { + base_type::open(T(const_cast(u0)), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0) + { + base_type::open(T(u0), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1) + { + base_type::open(u0, u1, -1); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1) + { + base_type::open(T(const_cast(u0), u1), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1) + { + base_type::open(T(u0, u1), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + template + void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2) + { + base_type::open(u0, u1, u2); + } + template + void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2) + { + base_type::open(T(const_cast(u0), u1, u2), -1, -1); + } +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------// + template + void open_impl(mpl::true_, U0& u0, const U1& u1, const U2& u2) + { + base_type::open(T(u0, u1, u2), -1, -1); + } +#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------// + void check_open() + { + if (this->is_open()) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("already open")); + } +}; + +} } // End namespaces iostreams, boost. + +#endif // BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_STREAM_BUFFER_HPP_INCLUDED diff --git a/boost/iostreams/detail/buffer.hpp b/boost/iostreams/detail/buffer.hpp new file mode 100644 index 0000000..59617f4 --- /dev/null +++ b/boost/iostreams/detail/buffer.hpp @@ -0,0 +1,229 @@ +// (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 BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // swap. +#include // allocator. +#include // member templates. +#include +#include // streamsize. +#include +#include // int_type_of. +#include +#include +#include + +namespace boost { 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 > +class basic_buffer { +private: +#ifndef BOOST_NO_STD_ALLOCATOR +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Alloc::template rebind::other allocator_type; +#else + typedef typename std::allocator_traits::template rebind_alloc allocator_type; + typedef std::allocator_traits allocator_traits; +#endif +#else + typedef std::allocator allocator_type; +#endif + static Ch* allocate(std::streamsize buffer_size); +public: + basic_buffer(); + basic_buffer(std::streamsize buffer_size); + ~basic_buffer(); + void resize(std::streamsize 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 +void swap(basic_buffer& lhs, basic_buffer& 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 > +class buffer : public basic_buffer { +private: + typedef basic_buffer base; +public: + typedef iostreams::char_traits traits_type; + using base::resize; + using base::data; + using base::size; + typedef Ch* const const_pointer; + buffer(std::streamsize 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 int_type_of::type fill(Source& src) + { + using namespace std; + std::streamsize keep; + if ((keep = static_cast(eptr_ - ptr_)) > 0) + traits_type::move( + this->data(), + ptr_, + static_cast(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 + bool flush(Sink& dest) + { + using namespace std; + std::streamsize amt = static_cast(eptr_ - ptr_); + std::streamsize result = iostreams::write_if(dest, ptr_, amt); + if (result < amt) { + traits_type::move( this->data(), + ptr_ + static_cast(result), + static_cast(amt - result) ); + } + this->set(0, amt - result); + return result != 0; + } +private: + Ch *ptr_, *eptr_; +}; + +template +void swap(buffer& lhs, buffer& rhs) +{ lhs.swap(rhs); } + +//--------------Implementation of basic_buffer--------------------------------// + +template +basic_buffer::basic_buffer() : buf_(0), size_(0) { } + +template +inline Ch* basic_buffer::allocate(std::streamsize buffer_size) +{ +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + return static_cast(allocator_type().allocate( + static_cast(buffer_size), 0)); +#else + allocator_type alloc; + return static_cast(allocator_traits::allocate(alloc, + static_cast(buffer_size))); +#endif +} + +template +basic_buffer::basic_buffer(std::streamsize buffer_size) + : buf_(allocate(buffer_size)), + size_(buffer_size) // Cast for SunPro 5.3. + { } + +template +inline basic_buffer::~basic_buffer() +{ + if (buf_) { +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + allocator_type().deallocate(buf_, + static_cast(size_)); +#else + allocator_type alloc; + allocator_traits::deallocate(alloc, buf_, + static_cast(size_)); +#endif + } +} + +template +inline void basic_buffer::resize(std::streamsize buffer_size) +{ + if (size_ != buffer_size) { + basic_buffer temp(buffer_size); + std::swap(size_, temp.size_); + std::swap(buf_, temp.buf_); + } +} + +template +void basic_buffer::swap(basic_buffer& rhs) +{ + std::swap(buf_, rhs.buf_); + std::swap(size_, rhs.size_); +} + +//--------------Implementation of buffer--------------------------------------// + +template +buffer::buffer(std::streamsize buffer_size) + : basic_buffer(buffer_size), ptr_(data()), eptr_(data() + buffer_size) { } + +template +inline void buffer::set(std::streamsize ptr, std::streamsize end) +{ + ptr_ = data() + ptr; + eptr_ = data() + end; +} + +template +inline void buffer::swap(buffer& rhs) +{ + base::swap(rhs); + std::swap(ptr_, rhs.ptr_); + std::swap(eptr_, rhs.eptr_); +} + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED diff --git a/boost/iostreams/detail/call_traits.hpp b/boost/iostreams/detail/call_traits.hpp new file mode 100644 index 0000000..be61237 --- /dev/null +++ b/boost/iostreams/detail/call_traits.hpp @@ -0,0 +1,32 @@ +// (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 BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct param_type { + typedef typename mpl::if_, T&, const T&>::type type; +}; + +template +struct value_type { + typedef typename mpl::if_, T&, T>::type type; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED //-----------// diff --git a/boost/iostreams/detail/char_traits.hpp b/boost/iostreams/detail/char_traits.hpp new file mode 100644 index 0000000..ce3eb6d --- /dev/null +++ b/boost/iostreams/detail/char_traits.hpp @@ -0,0 +1,63 @@ +// (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.) + +// Provides std::char_traits for libraries without templated streams. Should not +// be confused with , which defines the +// template boost::iostreams::char_traits. + +// See http://www.boost.org/libs/iostreams for documentation. + +#ifndef BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include // Make sure size_t is in std. +# include +# include +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// +# define BOOST_IOSTREAMS_CHAR_TRAITS(ch) std::char_traits< ch > +#else +# define BOOST_IOSTREAMS_CHAR_TRAITS(ch) boost::iostreams::detail::char_traits + +namespace boost { namespace iostreams { namespace detail { + +struct char_traits { + typedef char char_type; + typedef int int_type; + typedef std::streampos pos_type; + typedef std::streamoff off_type; + + // Note: this may not be not conforming, since it treats chars as unsigned, + // but is only used to test for equality. + static int compare(const char* lhs, const char* rhs, std::size_t n) + { return std::strncmp(lhs, rhs, n); } + static char* copy(char *dest, const char *src, std::size_t n) + { return static_cast(std::memcpy(dest, src, n)); } + static char* move(char *dest, const char *src, std::size_t n) + { return static_cast(std::memmove(dest, src, n)); } + static const char* find(const char* s, std::size_t n, const char& c) + { return (const char*) (const void*) std::memchr(s, c, n); } + static char to_char_type(const int& c) { return c; } + static int to_int_type(const char& c) { return c; } + static bool eq_int_type(const int& lhs, const int& rhs) + { return lhs == rhs; } + static int eof() { return EOF; } + static int not_eof(const int& c) { return c != EOF ? c : '\n'; } +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAR_TRAITS_HPP_INCLUDED diff --git a/boost/iostreams/detail/codecvt_helper.hpp b/boost/iostreams/detail/codecvt_helper.hpp new file mode 100644 index 0000000..0bd8d59 --- /dev/null +++ b/boost/iostreams/detail/codecvt_helper.hpp @@ -0,0 +1,214 @@ +// (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. + +// Contains the definition of the template codecvt_helper, useful for +// defining specializations of std::codecvt where state_type != mbstate_t. +// Compensates for the fact that some standard library implementations +// do not derive the primiary codecvt template from locale::facet or +// provide the correct member types and functions. + +// Usage: +// +// // In global namespace: +// BOOST_IOSTREAMS_CODECVT_SPEC(mystate) +// +// // In user namespace: +// template +// struct mycodecvt : codecvt_helper { ... }; +// +// // Or: +// struct mycodecvt : codecvt_helper { ... }; +// +// Etc. + +#ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // Put size_t in std, BOOST_MSVC, Dinkum. +#include +#include // min. +#include // size_t. +#include // locale, codecvt_base, codecvt. +#include + +//------------------Definition of traits--------------------------------------// + +namespace boost { namespace iostreams { namespace detail { + +#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------// + +template +struct codecvt_intern { typedef typename T::intern_type type; }; + +template +struct codecvt_extern { typedef typename T::extern_type type; }; + +#else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------// + +template +struct codecvt_intern { typedef typename T::from_type type; }; + +template +struct codecvt_extern { typedef typename T::to_type type; }; + +#endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------// + +template +struct codecvt_state { typedef typename T::state_type type; }; + +} } } // End namespaces detail, iostreams, boost. + +//------------------Definition of codecvt_impl--------------------------------// + +#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ + defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) || \ + defined(BOOST_IOSTREAMS_NO_LOCALE) \ + /**/ + +namespace boost { namespace iostreams { namespace detail { + +template +struct codecvt_impl : std::locale::facet, std::codecvt_base { +public: + typedef Intern intern_type; + typedef Extern extern_type; + typedef State state_type; + + codecvt_impl(std::size_t refs = 0) : std::locale::facet(refs) { } + + std::codecvt_base::result + in( State& state, const Extern* first1, const Extern* last1, + const Extern*& next1, Intern* first2, Intern* last2, + Intern*& next2 ) const + { + return do_in(state, first1, last1, next1, first2, last2, next2); + } + + std::codecvt_base::result + out( State& state, const Intern* first1, const Intern* last1, + const Intern*& next1, Extern* first2, Extern* last2, + Extern*& next2 ) const + { + return do_out(state, first1, last1, next1, first2, last2, next2); + } + + std::codecvt_base::result + unshift(State& state, Extern* first2, Extern* last2, Extern*& next2) const + { + return do_unshift(state, first2, last2, next2); + } + + bool always_noconv() const throw() { return do_always_noconv(); } + + int max_length() const throw() { return do_max_length(); } + + int encoding() const throw() { return do_encoding(); } + + int length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state, + const Extern* first1, const Extern* last1, + std::size_t len2 ) const throw() + { + return do_length(state, first1, last1, len2); + } +protected: + std::codecvt_base::result + virtual do_in( State&, const Extern*, const Extern*, const Extern*&, + Intern*, Intern*, Intern*& ) const + { + return std::codecvt_base::noconv; + } + + std::codecvt_base::result + virtual do_out( State&, const Intern*, const Intern*, const Intern*&, + Extern*, Extern*, Extern*& ) const + { + return std::codecvt_base::noconv; + } + + std::codecvt_base::result + virtual do_unshift(State&, Extern*, Extern*, Extern*&) const + { + return std::codecvt_base::ok; + } + + virtual bool do_always_noconv() const throw() { return true; } + + virtual int do_max_length() const throw() { return 1; } + + virtual int do_encoding() const throw() { return 1; } + + virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&, + const Extern* first1, const Extern* last1, + std::size_t len2 ) const throw() + { + return (std::min)(static_cast(last1 - first1), len2); + } +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // no primary codecvt definition, empty definition. + +//------------------Definition of BOOST_IOSTREAMS_CODECVT_SPEC----------------// + +#if defined(BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION) || \ + defined(BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION) \ + /**/ +# define BOOST_IOSTREAMS_CODECVT_SPEC(state) \ + namespace std { \ + template \ + class codecvt \ + : public ::boost::iostreams::detail::codecvt_impl< \ + Intern, Extern, state \ + > \ + { \ + public: \ + codecvt(std::size_t refs = 0) \ + : ::boost::iostreams::detail::codecvt_impl< \ + Intern, Extern, state \ + >(refs) \ + { } \ + static std::locale::id id; \ + }; \ + template \ + std::locale::id codecvt::id; \ + } \ + /**/ +#else +# define BOOST_IOSTREAMS_CODECVT_SPEC(state) +#endif // no primary codecvt definition, or empty definition. + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of codecvt_helper------------------------------// + +template +struct codecvt_helper : std::codecvt { + typedef Intern intern_type; + typedef Extern extern_type; + typedef State state_type; + codecvt_helper(std::size_t refs = 0) + #if !defined(BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T) + : std::codecvt(refs) + #else + : std::codecvt() + #endif + { } +#ifdef BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH + int max_length() const throw() { return do_max_length(); } +protected: + virtual int do_max_length() const throw() { return 1; } +#endif +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HELPER_HPP_INCLUDED diff --git a/boost/iostreams/detail/codecvt_holder.hpp b/boost/iostreams/detail/codecvt_holder.hpp new file mode 100644 index 0000000..13a9333 --- /dev/null +++ b/boost/iostreams/detail/codecvt_holder.hpp @@ -0,0 +1,63 @@ +// (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. + +// Contains machinery for performing code conversion. + +#ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // mbstate_t. +#include // codecvt, locale. +#include // HAS_MACRO_USE_FACET. +#include + +namespace boost { namespace iostreams { namespace detail { + +struct default_codecvt { + typedef wchar_t intern_type, from_type; + typedef char extern_type, to_type; + typedef std::mbstate_t state_type; +}; + +template +struct codecvt_holder { + typedef Codecvt codecvt_type; + const codecvt_type& get() const { return codecvt_; } + void imbue(const std::locale&) { } + Codecvt codecvt_; +}; + +template<> +struct codecvt_holder { + typedef std::codecvt codecvt_type; + codecvt_holder() { reset_codecvt(); } + const codecvt_type& get() const { return *codecvt_; } + void imbue(const std::locale& loc) + { + loc_ = loc; + reset_codecvt(); + } + void reset_codecvt() + { + using namespace std; + #ifndef BOOST_HAS_MACRO_USE_FACET + codecvt_ = & use_facet< codecvt_type >(loc_); + #else + codecvt_ = & _USE(loc_, codecvt_type); + #endif + } + std::locale loc_; // Prevent codecvt_ from being freed. + const codecvt_type* codecvt_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CODECVT_HOLDER_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/auto_link.hpp b/boost/iostreams/detail/config/auto_link.hpp new file mode 100644 index 0000000..be7dc63 --- /dev/null +++ b/boost/iostreams/detail/config/auto_link.hpp @@ -0,0 +1,49 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#if defined(BOOST_EXTERNAL_LIB_NAME) +# if defined(BOOST_MSVC) \ + || defined(__BORLANDC__) && !defined(__clang__) \ + || (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) \ + || (defined(__ICL) && defined(_MSC_EXTENSIONS)) \ + /**/ +# pragma comment(lib, BOOST_EXTERNAL_LIB_NAME) +# endif +# undef BOOST_EXTERNAL_LIB_NAME +#endif + +//------------------Enable automatic library variant selection----------------// + +#if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_iostreams + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +#endif // auto-linking disabled + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/bzip2.hpp b/boost/iostreams/detail/config/bzip2.hpp new file mode 100644 index 0000000..4c8bc91 --- /dev/null +++ b/boost/iostreams/detail/config/bzip2.hpp @@ -0,0 +1,50 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_STRINGIZE. + +#if defined(BOOST_BZIP2_BINARY) +# if defined(BOOST_MSVC) || \ + defined(BOOST_BORLANDC) || \ + (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICL) && defined(_MSC_EXTENSIONS)) \ + /**/ + +// Specify the name of the .lib file. +# pragma comment(lib, BOOST_STRINGIZE(BOOST_BZIP2_BINARY)) +# endif +#else +# if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_bzip2 + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/codecvt.hpp b/boost/iostreams/detail/config/codecvt.hpp new file mode 100644 index 0000000..13eb394 --- /dev/null +++ b/boost/iostreams/detail/config/codecvt.hpp @@ -0,0 +1,81 @@ +// (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 BOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED + +#include +#include +#include +#include + +#if defined(_MSC_VER) +# pragma once +#endif + +//------------------Support for codecvt with user-defined state types---------// + +#if defined(__MSL_CPP__) || defined(__LIBCOMO__) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, <= 0x450) || \ + defined(_LIBCPP_VERSION) \ + /**/ +# define BOOST_IOSTREAMS_NO_PRIMARY_CODECVT_DEFINITION +#endif + +#if defined(__GLIBCPP__) || defined(__GLIBCXX__) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, > 0x450) \ + /**/ +# define BOOST_IOSTREAMS_EMPTY_PRIMARY_CODECVT_DEFINITION +#endif + +//------------------Check for codecvt ctor taking a reference count-----------// + +#if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) || \ + BOOST_WORKAROUND(_STLPORT_VERSION, < 0x461) \ + /**/ +# define BOOST_IOSTREAMS_NO_CODECVT_CTOR_FROM_SIZE_T +#endif + +//------------------Normalize codecvt::length---------------------------------// + +#if !defined(__MSL_CPP__) && !defined(__LIBCOMO__) && !defined(__clang__) && \ + (!defined(BOOST_RWSTD_VER) || BOOST_RWSTD_VER < 0x04010300) && \ + (!defined(__MACH__) || !defined(__INTEL_COMPILER)) + /**/ +# define BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER const +#else +# define BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER +#endif + +//------------------Check for codecvt::max_length-----------------------------// + +#if BOOST_WORKAROUND(_STLPORT_VERSION, < 0x461) +# define BOOST_IOSTREAMS_NO_CODECVT_MAX_LENGTH +#endif + +//------------------Put mbstate_t and codecvt in std--------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +# include +#endif + +// From Robert Ramey's version of utf8_codecvt_facet. +namespace std { + +#if defined(__LIBCOMO__) + using ::mbstate_t; +#elif defined(BOOST_DINKUMWARE_STDLIB) && !defined(BOOST_BORLANDC) + using ::mbstate_t; +#elif defined(__SGI_STL_PORT) +#elif defined(BOOST_NO_STDC_NAMESPACE) + using ::codecvt; + using ::mbstate_t; +#endif + +} // End namespace std. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_CODECVT_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/disable_warnings.hpp b/boost/iostreams/detail/config/disable_warnings.hpp new file mode 100644 index 0000000..344c6c1 --- /dev/null +++ b/boost/iostreams/detail/config/disable_warnings.hpp @@ -0,0 +1,30 @@ +// (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. + +#include // BOOST_MSVC. +#include // BOOST_WORKAROUND. + +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4127) // Conditional expression is constant. +# pragma warning(disable:4130) // Logical operation on address of string constant. +# pragma warning(disable:4224) // Parameter previously defined as type. +# pragma warning(disable:4244) // Conversion: possible loss of data. +# pragma warning(disable:4512) // Assignment operator could not be generated. +# pragma warning(disable:4706) // Assignment within conditional expression. +# if BOOST_WORKAROUND(BOOST_MSVC, >= 1400) +# pragma warning(disable:6334) // sizeof applied to an expression with an operator. +# endif +#else +# if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) +# pragma warn -8008 // Condition always true/false. +# pragma warn -8066 // Unreachable code. +# pragma warn -8071 // Conversion may lose significant digits. +# pragma warn -8072 // Suspicious pointer arithmetic. +# pragma warn -8080 // identifier declared but never used. +# endif +#endif diff --git a/boost/iostreams/detail/config/dyn_link.hpp b/boost/iostreams/detail/config/dyn_link.hpp new file mode 100644 index 0000000..cc8c73b --- /dev/null +++ b/boost/iostreams/detail/config/dyn_link.hpp @@ -0,0 +1,46 @@ +// (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. + +// Adapted from http://www.boost.org/more/separate_compilation.html, by +// John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +//------------------Enable dynamic linking on windows-------------------------// + +#ifdef BOOST_HAS_DECLSPEC +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# ifdef BOOST_IOSTREAMS_SOURCE +# define BOOST_IOSTREAMS_DECL __declspec(dllexport) +# else +# define BOOST_IOSTREAMS_DECL __declspec(dllimport) +# endif +# endif +//--------------Enable dynamic linking for non-windows---------------------// +#else // BOOST_HAS_DECLSPEC +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# ifdef BOOST_IOSTREAMS_SOURCE +# define BOOST_IOSTREAMS_DECL BOOST_SYMBOL_EXPORT +# else +# define BOOST_IOSTREAMS_DECL BOOST_SYMBOL_IMPORT +# endif +# endif +#endif + +#ifndef BOOST_IOSTREAMS_DECL +# define BOOST_IOSTREAMS_DECL +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_DYN_LINK_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/enable_warnings.hpp b/boost/iostreams/detail/config/enable_warnings.hpp new file mode 100644 index 0000000..f04f525 --- /dev/null +++ b/boost/iostreams/detail/config/enable_warnings.hpp @@ -0,0 +1,18 @@ +// (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. + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#else +# if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) +# pragma warn .8008 // Condition always true/false. +# pragma warn .8066 // Unreachable code. +# pragma warn .8071 // Conversion may lose significant digits. +# pragma warn .8072 // Suspicious pointer arithmetic. +# pragma warn .8080 // identifier declared but never used. +# endif +#endif diff --git a/boost/iostreams/detail/config/fpos.hpp b/boost/iostreams/detail/config/fpos.hpp new file mode 100644 index 0000000..a583542 --- /dev/null +++ b/boost/iostreams/detail/config/fpos.hpp @@ -0,0 +1,45 @@ +/* + * 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. + + * File: boost/iostreams/detail/execute.hpp + * Date: Thu Dec 06 13:21:54 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the preprocessor symbol BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS for + * platforms that use the implementation of std::fpos from the Dinkumware + * Standard Library. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +# if (defined(_YVALS) || defined(_CPPLIB_VER)) && !defined(__SGI_STL_PORT) && \ + !defined(_STLPORT_VERSION) && !defined(__QNX__) && !defined(_VX_CPU) && !defined(__VXWORKS__) \ + && !((defined(BOOST_MSVC) || defined(BOOST_CLANG)) && _MSVC_STL_VERSION >= 141) \ + && !defined(_LIBCPP_VERSION) + /**/ + +#include + +# define BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +#if !defined(_FPOSOFF) +#define BOOST_IOSTREAMS_FPOSOFF(fp) ((long long)(fp)) +#else +#define BOOST_IOSTREAMS_FPOSOFF(fp) _FPOSOFF(fp) +#endif + +# endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_FPOS_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/gcc.hpp b/boost/iostreams/detail/config/gcc.hpp new file mode 100644 index 0000000..ff6892a --- /dev/null +++ b/boost/iostreams/detail/config/gcc.hpp @@ -0,0 +1,27 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_INTEL. + +#if defined(__GNUC__) && !defined(BOOST_INTEL) +# define BOOST_IOSTREAMS_GCC (__GNUC__ * 100 + __GNUC_MINOR__) +# define BOOST_IOSTREAMS_GCC_WORKAROUND_GUARD 1 +#else +# define BOOST_IOSTREAMS_GCC_WORKAROUND_GUARD 0 +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_GCC_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/limits.hpp b/boost/iostreams/detail/config/limits.hpp new file mode 100644 index 0000000..155d6b0 --- /dev/null +++ b/boost/iostreams/detail/config/limits.hpp @@ -0,0 +1,19 @@ +// (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 BOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED + +#ifndef BOOST_IOSTREAMS_MAX_FORWARDING_ARITY +# define BOOST_IOSTREAMS_MAX_FORWARDING_ARITY 3 +#endif + +#ifndef BOOST_IOSTREAMS_MAX_EXECUTE_ARITY +# define BOOST_IOSTREAMS_MAX_EXECUTE_ARITY 5 +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_LIMITS_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/overload_resolution.hpp b/boost/iostreams/detail/config/overload_resolution.hpp new file mode 100644 index 0000000..5b98221 --- /dev/null +++ b/boost/iostreams/detail/config/overload_resolution.hpp @@ -0,0 +1,30 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include + +#if !defined(BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION) +# if BOOST_WORKAROUND(__MWERKS__, <= 0x3003) || \ + BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) \ + /**/ +# define BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/rtl.hpp b/boost/iostreams/detail/config/rtl.hpp new file mode 100644 index 0000000..b1a046f --- /dev/null +++ b/boost/iostreams/detail/config/rtl.hpp @@ -0,0 +1,72 @@ +/* + * 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. + * + * Defines preprocessor symbols expanding to the names of functions in the + * C runtime library used to access file descriptors and to the type used + * to store file offsets for seeking. + * + * File: boost/iostreams/detail/config/rtl.hpp + * Date: Wed Dec 26 11:58:11 MST 2007 + * + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED + +#include +#include + +// Handle open, close, read, and write +#ifdef BOOST_BORLANDC +# define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_rtl_, x) +#elif defined BOOST_IOSTREAMS_WINDOWS +# define BOOST_IOSTREAMS_RTL(x) BOOST_JOIN(_, x) +#else +# define BOOST_IOSTREAMS_RTL(x) ::x // Distinguish from member function named x +#endif +#define BOOST_IOSTREAMS_FD_OPEN BOOST_IOSTREAMS_RTL(open) +#define BOOST_IOSTREAMS_FD_CLOSE BOOST_IOSTREAMS_RTL(close) +#define BOOST_IOSTREAMS_FD_READ BOOST_IOSTREAMS_RTL(read) +#define BOOST_IOSTREAMS_FD_WRITE BOOST_IOSTREAMS_RTL(write) + +// Handle lseek, off_t, ftruncate, and stat +#ifdef BOOST_IOSTREAMS_WINDOWS +# if defined(BOOST_MSVC) || defined(__MSVCRT__) // MSVC, MinGW +# define BOOST_IOSTREAMS_FD_SEEK _lseeki64 +# define BOOST_IOSTREAMS_FD_OFFSET __int64 +# else // Borland, Metrowerks, ... +# define BOOST_IOSTREAMS_FD_SEEK lseek +# define BOOST_IOSTREAMS_FD_OFFSET long +# endif +#else // Non-windows +# if defined(_LARGEFILE64_SOURCE) && !defined(__APPLE__) && \ + (!defined(_FILE_OFFSET_BITS) || _FILE_OFFSET_BITS != 64) || \ + defined(_AIX) && !defined(_LARGE_FILES) || \ + defined(BOOST_IOSTREAMS_HAS_LARGE_FILE_EXTENSIONS) + /**/ + + /* Systems with transitional extensions for large file support */ + +# define BOOST_IOSTREAMS_FD_SEEK lseek64 +# define BOOST_IOSTREAMS_FD_TRUNCATE ftruncate64 +# define BOOST_IOSTREAMS_FD_MMAP mmap64 +# define BOOST_IOSTREAMS_FD_STAT stat64 +# define BOOST_IOSTREAMS_FD_FSTAT fstat64 +# define BOOST_IOSTREAMS_FD_OFFSET off64_t +# else +# define BOOST_IOSTREAMS_FD_SEEK lseek +# define BOOST_IOSTREAMS_FD_TRUNCATE ftruncate +# define BOOST_IOSTREAMS_FD_MMAP mmap +# define BOOST_IOSTREAMS_FD_STAT stat +# define BOOST_IOSTREAMS_FD_FSTAT fstat +# define BOOST_IOSTREAMS_FD_OFFSET off_t +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_RTL_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/unreachable_return.hpp b/boost/iostreams/detail/config/unreachable_return.hpp new file mode 100644 index 0000000..65fba60 --- /dev/null +++ b/boost/iostreams/detail/config/unreachable_return.hpp @@ -0,0 +1,24 @@ +// (C) Copyright 2010 Daniel James +// 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_UNREACHABLE_RETURN_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_UNREACHABLE_RETURN_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#if defined(_MSC_VER) || defined(__GNUC__) +#define BOOST_IOSTREAMS_UNREACHABLE_RETURN(x) \ + BOOST_UNREACHABLE_RETURN(x) +#else +#define BOOST_IOSTREAMS_UNREACHABLE_RETURN(x) \ + return x; +#endif + +#endif diff --git a/boost/iostreams/detail/config/wide_streams.hpp b/boost/iostreams/detail/config/wide_streams.hpp new file mode 100644 index 0000000..ca8dff3 --- /dev/null +++ b/boost/iostreams/detail/config/wide_streams.hpp @@ -0,0 +1,54 @@ +// (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. + +// Adapted from http://www.boost.org/more/separate_compilation.html, by +// John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED + +#include +#include +#include + +#if defined(_MSC_VER) +# pragma once +#endif + +//------------------Templated stream support----------------------------------// + +// From boost/dynamic_bitset.hpp; thanks to Matthias Troyer for cray patch. +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# if defined(__STL_CONFIG_H) && \ + !defined (__STL_USE_NEW_IOSTREAMS) && !defined(__crayx1) \ + /**/ +# define BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + +//------------------Wide stream support---------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +# if defined(BOOST_IOSTREAMS_NO_STREAM_TEMPLATES) || \ + defined (BOOST_NO_STD_WSTREAMBUF) && \ + ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \ + /**/ +# define BOOST_IOSTREAMS_NO_WIDE_STREAMS +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS + +//------------------Locale support--------------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +# if defined(BOOST_NO_STD_LOCALE) && \ + ( !defined(__MSL_CPP__) || defined(_MSL_NO_WCHART_CPP_SUPPORT) ) \ + /**/ +# define BOOST_IOSTREAMS_NO_LOCALE +# endif +#endif // #ifndef BOOST_IOSTREAMS_NO_LOCALE + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WIDE_STREAMS_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/windows_posix.hpp b/boost/iostreams/detail/config/windows_posix.hpp new file mode 100644 index 0000000..4e73c50 --- /dev/null +++ b/boost/iostreams/detail/config/windows_posix.hpp @@ -0,0 +1,25 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-2007 Jonathan Turkanis +// (C) Copyright 2002, 2003 Beman Dawes Boost.Filesystem +// 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_CONFIG_WINDOWS_POSIX_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED + +//------------------From boost/libs/filesystem/src/path_posix_windows.cpp-----// + +// BOOST_IOSTREAMS_POSIX or BOOST_IOSTREAMS_WINDOWS specify which API to use. +#if !defined( BOOST_IOSTREAMS_WINDOWS ) && !defined( BOOST_IOSTREAMS_POSIX ) +# if (defined(_WIN32) || defined(__WIN32__) || defined(WIN32)) && \ + !defined(__CYGWIN__) \ + /**/ +# define BOOST_IOSTREAMS_WINDOWS +# else +# define BOOST_IOSTREAMS_POSIX +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_WINDOWS_POSIX_HPP_INCLUDED diff --git a/boost/iostreams/detail/config/zlib.hpp b/boost/iostreams/detail/config/zlib.hpp new file mode 100644 index 0000000..576f5ac --- /dev/null +++ b/boost/iostreams/detail/config/zlib.hpp @@ -0,0 +1,50 @@ +// (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. + +// Adapted from and from +// http://www.boost.org/more/separate_compilation.html, by John Maddock. + +#ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_STRINGIZE. + +#if defined(BOOST_ZLIB_BINARY) +# if defined(BOOST_MSVC) || \ + defined(BOOST_BORLANDC) || \ + (defined(__MWERKS__) && defined(_WIN32) && (__MWERKS__ >= 0x3000)) || \ + (defined(__ICL) && defined(_MSC_EXTENSIONS)) \ + /**/ + +// Specify the name of the .lib file. +# pragma comment(lib, BOOST_STRINGIZE(BOOST_ZLIB_BINARY)) +# endif +#else +# if !defined(BOOST_IOSTREAMS_SOURCE) && \ + !defined(BOOST_ALL_NO_LIB) && \ + !defined(BOOST_IOSTREAMS_NO_LIB) \ + /**/ + +// Set the name of our library, this will get undef'ed by auto_link.hpp +// once it's done with it. +# define BOOST_LIB_NAME boost_zlib + +// If we're importing code from a dll, then tell auto_link.hpp about it. +# if defined(BOOST_ALL_DYN_LINK) || defined(BOOST_IOSTREAMS_DYN_LINK) +# define BOOST_DYN_LINK +# endif + +// And include the header that does the work. +# include +# endif +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED diff --git a/boost/iostreams/detail/counted_array.hpp b/boost/iostreams/detail/counted_array.hpp new file mode 100644 index 0000000..c0cd8a1 --- /dev/null +++ b/boost/iostreams/detail/counted_array.hpp @@ -0,0 +1,74 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED + +#include // min. +#include // size_t +#include // char_traits +#include +#include +#include // streamsize. + +namespace boost { namespace iostreams { namespace detail { + +template +class counted_array_source { +public: + typedef Ch char_type; + typedef source_tag category; + counted_array_source(const Ch* buf, std::streamsize size) + : buf_(buf), ptr_(0), end_(size) + { } + std::streamsize read(Ch* s, std::streamsize n) + { + using namespace std; + streamsize result = (std::min)(n, end_ - ptr_); + char_traits::copy( + s, + buf_ + ptr_, + static_cast(result) + ); + ptr_ += result; + return result; + } + std::streamsize count() const { return ptr_; } +private: + const Ch* buf_; + std::streamsize ptr_, end_; +}; + +template +struct counted_array_sink { +public: + typedef Ch char_type; + typedef sink_tag category; + counted_array_sink(Ch* buf, std::streamsize size) + : buf_(buf), ptr_(0), end_(size) + { } + std::streamsize write(const Ch* s, std::streamsize n) + { + using namespace std; + std::streamsize result = (std::min)(n, end_ - ptr_); + char_traits::copy( + buf_ + ptr_, + s, + static_cast(result) + ); + ptr_ += result; + return result; + } + std::streamsize count() const { return ptr_; } +private: + Ch* buf_; + std::streamsize ptr_, end_; +}; + +} } } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_COUNTED_ARRAY_HPP_INCLUDED diff --git a/boost/iostreams/detail/current_directory.hpp b/boost/iostreams/detail/current_directory.hpp new file mode 100644 index 0000000..374444c --- /dev/null +++ b/boost/iostreams/detail/current_directory.hpp @@ -0,0 +1,65 @@ +/* + * 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. + + * File: boost/iostreams/detail/execute.hpp + * Date: Thu Dec 06 13:21:54 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the function boost::iostreams::detail::current_directory, used by + * boost::iostreams::detail::absolute_path. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED + +#include // make sure size_t is in std. +#include // size_t +#include +#include +#include +#include +#ifdef BOOST_IOSTREAMS_WINDOWS +# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +# include +#else +# include // sysconf. +#endif + +// Must come last. +#include + +namespace boost { namespace iostreams { namespace detail { + +// Returns the current working directory +inline std::string current_directory() +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD length; + basic_buffer buf(MAX_PATH); + while (true) { + length = ::GetCurrentDirectoryA(buf.size(), buf.data()); + if (!length) + throw_system_failure("failed determining current directory"); + if (length < static_cast(buf.size())) + break; + buf.resize(buf.size() * 2); + } + return std::string(buf.data(), length); +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + basic_buffer buf(pathconf(".", _PC_PATH_MAX)); + if (!getcwd(buf.data(), static_cast(buf.size()))) + throw_system_failure("failed determining current directory"); + return std::string(buf.data()); +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +} } } // End namespaces detail, iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED diff --git a/boost/iostreams/detail/default_arg.hpp b/boost/iostreams/detail/default_arg.hpp new file mode 100644 index 0000000..c443e98 --- /dev/null +++ b/boost/iostreams/detail/default_arg.hpp @@ -0,0 +1,21 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +// Obsolete. Remove. +#define BOOST_IOSTREAMS_DEFAULT_ARG(arg) arg + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED diff --git a/boost/iostreams/detail/dispatch.hpp b/boost/iostreams/detail/dispatch.hpp new file mode 100644 index 0000000..35cf244 --- /dev/null +++ b/boost/iostreams/detail/dispatch.hpp @@ -0,0 +1,41 @@ +// (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 BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_DEDUCED_TYPENAME. +#include +#include // category_of. +#include +#include + +namespace boost { namespace iostreams {namespace detail { + +template< typename T, typename Tag1, typename Tag2, + typename Tag3 = mpl::void_, typename Tag4 = mpl::void_, + typename Tag5 = mpl::void_, typename Tag6 = mpl::void_, + typename Category = + BOOST_DEDUCED_TYPENAME category_of::type > +struct dispatch + : iostreams::select< // Disambiguation for Tru64. + is_convertible, Tag1, + is_convertible, Tag2, + is_convertible, Tag3, + is_convertible, Tag4, + is_convertible, Tag5, + is_convertible, Tag6 + > + { }; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED diff --git a/boost/iostreams/detail/double_object.hpp b/boost/iostreams/detail/double_object.hpp new file mode 100644 index 0000000..efb3b78 --- /dev/null +++ b/boost/iostreams/detail/double_object.hpp @@ -0,0 +1,114 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-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. + +// Contains the definition of the class template +// boost::iostreams::detail::double_object, which is similar to compressed pair +// except that both members of the pair have the same type, and +// compression occurs only if requested using a boolean template +// parameter. + +#ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // swap. +#include +#include +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) +# include +#else +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +template +class single_object_holder { +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + single_object_holder() { } + single_object_holder(param_type t) : first_(t) { } + reference first() { return first_; } + const_reference first() const { return first_; } + reference second() { return first_; } + const_reference second() const { return first_; } + void swap(single_object_holder& o) + { std::swap(first_, o.first_); } +private: + T first_; +}; + +template +struct double_object_holder { +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + double_object_holder() { } + double_object_holder(param_type t1, param_type t2) + : first_(t1), second_(t2) { } + reference first() { return first_; } + const_reference first() const { return first_; } + reference second() { return second_; } + const_reference second() const { return second_; } + void swap(double_object_holder& d) + { + std::swap(first_, d.first_); + std::swap(second_, d.second_); + } +private: + T first_, second_; +}; + +template +class double_object + : public mpl::if_< + IsDouble, + double_object_holder, + single_object_holder + >::type +{ +private: + typedef typename + mpl::if_< + IsDouble, + double_object_holder, + single_object_holder + >::type base_type; +public: +#if BOOST_WORKAROUND(__MWERKS__, > 0x3003) + typedef Metrowerks::call_traits traits_type; +#else + typedef boost::call_traits traits_type; +#endif + typedef typename traits_type::param_type param_type; + typedef typename traits_type::reference reference; + typedef typename traits_type::const_reference const_reference; + double_object() : base_type() {} + double_object(param_type t1, param_type t2) + : base_type(t1, t2) { } + bool is_double() const { return IsDouble::value; } +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DOUBLE_OBJECT_HPP_INCLUDED diff --git a/boost/iostreams/detail/enable_if_stream.hpp b/boost/iostreams/detail/enable_if_stream.hpp new file mode 100644 index 0000000..2ead3d9 --- /dev/null +++ b/boost/iostreams/detail/enable_if_stream.hpp @@ -0,0 +1,33 @@ +// (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 BOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_NO_SFINAE. +#include +#include +#include // is_std_io. + +#if !defined(BOOST_NO_SFINAE) && \ + !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) +# define BOOST_IOSTREAMS_ENABLE_IF_STREAM(T) \ + , typename boost::enable_if< boost::iostreams::is_std_io >::type* = 0 \ + /**/ +# define BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) \ + , typename boost::disable_if< boost::iostreams::is_std_io >::type* = 0 \ + /**/ +#else +# define BOOST_IOSTREAMS_ENABLE_IF_STREAM(T) +# define BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ENABLE_IF_STREAM_HPP_INCLUDED diff --git a/boost/iostreams/detail/error.hpp b/boost/iostreams/detail/error.hpp new file mode 100644 index 0000000..85cbd98 --- /dev/null +++ b/boost/iostreams/detail/error.hpp @@ -0,0 +1,45 @@ +// (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 BOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // failure. + +namespace boost { namespace iostreams { namespace detail { + +inline BOOST_IOSTREAMS_FAILURE cant_read() +{ return BOOST_IOSTREAMS_FAILURE("no read access"); } + +inline BOOST_IOSTREAMS_FAILURE cant_write() +{ return BOOST_IOSTREAMS_FAILURE("no write access"); } + +inline BOOST_IOSTREAMS_FAILURE cant_seek() +{ return BOOST_IOSTREAMS_FAILURE("no random access"); } + +inline BOOST_IOSTREAMS_FAILURE bad_read() +{ return BOOST_IOSTREAMS_FAILURE("bad read"); } + +inline BOOST_IOSTREAMS_FAILURE bad_putback() +{ return BOOST_IOSTREAMS_FAILURE("putback buffer full"); } + +inline BOOST_IOSTREAMS_FAILURE bad_write() +{ return BOOST_IOSTREAMS_FAILURE("bad write"); } + +inline BOOST_IOSTREAMS_FAILURE write_area_exhausted() +{ return BOOST_IOSTREAMS_FAILURE("write area exhausted"); } + +inline BOOST_IOSTREAMS_FAILURE bad_seek() +{ return BOOST_IOSTREAMS_FAILURE("bad seek"); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_ERROR_HPP_INCLUDED diff --git a/boost/iostreams/detail/execute.hpp b/boost/iostreams/detail/execute.hpp new file mode 100644 index 0000000..e5a9f74 --- /dev/null +++ b/boost/iostreams/detail/execute.hpp @@ -0,0 +1,135 @@ +/* + * 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. + + * File: boost/iostreams/detail/execute.hpp + * Date: Thu Dec 06 13:21:54 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + + * Defines the overloaded function template + * boost::iostreams::detail::execute_all() and the function template + * boost::iostreams::detail::execute_foreach(). + * + * execute_all() invokes a primary operation and performs a sequence of cleanup + * operations, returning the result of the primary operation if no exceptions + * are thrown. If one of the operations throws an exception, performs the + * remaining operations and rethrows the initial exception. + * + * execute_foreach() is a variant of std::foreach which invokes a function + * object for each item in a sequence, catching all execptions and rethrowing + * the first caught exception after the function object has been invoked on each + * item. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include // MAX_EXECUTE_ARITY +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +// Helper for class template execute_traits. +template +struct execute_traits_impl { + typedef Result result_type; + template + static Result execute(Op op) { return op(); } +}; + +// Specialization for void return. For simplicity, execute() returns int +// for operations returning void. This could be avoided with additional work. +template<> +struct execute_traits_impl { + typedef int result_type; + template + static int execute(Op op) { op(); return 0; } +}; + +// Deduces the result type of Op and allows uniform treatment of operations +// returning void and non-void. +template< typename Op, + typename Result = // VC6.5 workaround. + #if !defined(BOOST_NO_RESULT_OF) && \ + !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) + typename boost::result_of::type + #else + BOOST_DEDUCED_TYPENAME Op::result_type + #endif + > +struct execute_traits + : execute_traits_impl + { }; + +// Implementation with no cleanup operations. +template +typename execute_traits::result_type +execute_all(Op op) +{ + return execute_traits::execute(op); +} + +// Implementation with one or more cleanup operations +#define BOOST_PP_LOCAL_MACRO(n) \ + template \ + typename execute_traits::result_type \ + execute_all(Op op, BOOST_PP_ENUM_BINARY_PARAMS(n, C, c)) \ + { \ + typename execute_traits::result_type r; \ + try { \ + r = boost::iostreams::detail::execute_all( \ + op BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS(BOOST_PP_DEC(n), c) \ + ); \ + } catch (...) { \ + try { \ + BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ + } catch (...) { } \ + throw; \ + } \ + BOOST_PP_CAT(c, BOOST_PP_DEC(n))(); \ + return r; \ + } \ + /**/ + +#define BOOST_PP_LOCAL_LIMITS (1, BOOST_IOSTREAMS_MAX_EXECUTE_ARITY) +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO + +template +Op execute_foreach(InIt first, InIt last, Op op) +{ + if (first == last) + return op; + try { + op(*first); + } catch (...) { + try { + ++first; + boost::iostreams::detail::execute_foreach(first, last, op); + } catch (...) { } + throw; + } + ++first; + return boost::iostreams::detail::execute_foreach(first, last, op); +} + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_EXECUTE_HPP_INCLUDED diff --git a/boost/iostreams/detail/file_handle.hpp b/boost/iostreams/detail/file_handle.hpp new file mode 100644 index 0000000..d797efb --- /dev/null +++ b/boost/iostreams/detail/file_handle.hpp @@ -0,0 +1,32 @@ +/* + * 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. + * + * File: boost/iostreams/detail/file_handle.hpp + * Date: Sun Jun 22 14:23:12 MDT 2008 + * Copyright: 2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the type boost::iostreams::detail::file_handle, representing an + * operating system file handle. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED + +#include + +namespace boost { namespace iostreams { namespace detail { + +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* file_handle; // A.k.a. HANDLE +#else + typedef int file_handle; +#endif + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FILE_HANDLE_HPP_INCLUDED diff --git a/boost/iostreams/detail/forward.hpp b/boost/iostreams/detail/forward.hpp new file mode 100644 index 0000000..4e78f1e --- /dev/null +++ b/boost/iostreams/detail/forward.hpp @@ -0,0 +1,113 @@ +// (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 BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC, BOOST_NO_SFINAE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +//------Macros for defining forwarding constructors and open overloads--------// + +// +// Macro: BOOST_IOSTREAMS_FORWARD(class, impl, device, params, args) +// Description: Defines constructors and overloads of 'open' which construct +// a device using the specified argument list and pass it to the specified +// helper function +// class - The class name +// impl - The helper function +// device - The device type +// params - The list of formal parameters trailing the device parameter in +// the helper function's signature +// params - The list of arguments passed to the helper function, following the +// device argument +// +#define BOOST_IOSTREAMS_FORWARD(class, impl, device, params, args) \ + class(const device& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + class(device& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + class(const ::boost::reference_wrapper& ref params()) \ + { this->impl(ref args()); } \ + void open(const device& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + void open(device& t params()) \ + { this->impl(::boost::iostreams::detail::wrap(t) args()); } \ + void open(const ::boost::reference_wrapper& ref params()) \ + { this->impl(ref args()); } \ + BOOST_PP_REPEAT_FROM_TO( \ + 1, BOOST_PP_INC(BOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \ + BOOST_IOSTREAMS_FORWARDING_CTOR, (class, impl, device) \ + ) \ + BOOST_PP_REPEAT_FROM_TO( \ + 1, BOOST_PP_INC(BOOST_IOSTREAMS_MAX_FORWARDING_ARITY), \ + BOOST_IOSTREAMS_FORWARDING_FN, (class, impl, device) \ + ) \ + /**/ +#define BOOST_IOSTREAMS_FORWARDING_CTOR(z, n, tuple) \ + template \ + BOOST_PP_TUPLE_ELEM(3, 0, tuple) \ + (BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u) \ + BOOST_IOSTREAMS_DISABLE_IF_SAME(U0, BOOST_PP_TUPLE_ELEM(3, 2, tuple))) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + (BOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \ + template< typename U100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), typename U) > \ + BOOST_PP_TUPLE_ELEM(3, 0, tuple) \ + ( U100& u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_DEC(n), const U, &u) \ + BOOST_IOSTREAMS_DISABLE_IF_SAME(U100, BOOST_PP_TUPLE_ELEM(3, 2, tuple))) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + ( u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), u)) ); } \ + /**/ +#define BOOST_IOSTREAMS_FORWARDING_FN(z, n, tuple) \ + template \ + void open(BOOST_PP_ENUM_BINARY_PARAMS_Z(z, n, const U, &u) \ + BOOST_IOSTREAMS_DISABLE_IF_SAME(U0, BOOST_PP_TUPLE_ELEM(3, 2, tuple))) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( BOOST_PP_TUPLE_ELEM(3, 2, tuple) \ + (BOOST_PP_ENUM_PARAMS_Z(z, n, u)) ); } \ + template< typename U100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), typename U) > \ + void open \ + ( U100& u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_BINARY_PARAMS_Z(z, BOOST_PP_DEC(n), const U, &u) \ + BOOST_IOSTREAMS_DISABLE_IF_SAME(U100, BOOST_PP_TUPLE_ELEM(3, 2, tuple))) \ + { this->BOOST_PP_TUPLE_ELEM(3, 1, tuple) \ + ( u100 BOOST_PP_COMMA_IF(BOOST_PP_DEC(n)) \ + BOOST_PP_ENUM_PARAMS_Z(z, BOOST_PP_DEC(n), u) ); } \ + /**/ + +// Disable forwarding constructors if first parameter type is the same +// as the device type +#if !defined(BOOST_NO_SFINAE) && \ + !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x592)) +# define BOOST_IOSTREAMS_DISABLE_IF_SAME(device, param) \ + , typename boost::disable_if< boost::is_same >::type* = 0 \ + /**/ +#else +# define BOOST_IOSTREAMS_DISABLE_IF_SAME(device, param) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED diff --git a/boost/iostreams/detail/fstream.hpp b/boost/iostreams/detail/fstream.hpp new file mode 100644 index 0000000..848258d --- /dev/null +++ b/boost/iostreams/detail/fstream.hpp @@ -0,0 +1,33 @@ +// (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 BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include +#else +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::basic_ifstream +# define BOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::basic_ofstream +# define BOOST_IOSTREAMS_BASIC_FSTREAM(Ch, Tr) std::basic_fstream +# define BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::basic_filebuf +#else +# define BOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::ifstream +# define BOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::ofstream +# define BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::filebuf +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FSTREAM_HPP_INCLUDED diff --git a/boost/iostreams/detail/functional.hpp b/boost/iostreams/detail/functional.hpp new file mode 100644 index 0000000..61c7a37 --- /dev/null +++ b/boost/iostreams/detail/functional.hpp @@ -0,0 +1,189 @@ +/* + * 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. + + * File: boost/iostreams/detail/functional.hpp + * Date: Sun Dec 09 05:38:03 MST 2007 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + + * Defines several function objects and object generators for use with + * execute_all() + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // BOOST_IOS + +namespace boost { namespace iostreams { namespace detail { + + // Function objects and object generators for invoking + // boost::iostreams::close + +template +class device_close_operation { +public: + typedef void result_type; + device_close_operation(T& t, BOOST_IOS::openmode which) + : t_(t), which_(which) + { } + void operator()() const { boost::iostreams::close(t_, which_); } +private: + BOOST_DELETED_FUNCTION(device_close_operation& operator=(const device_close_operation&)) + T& t_; + BOOST_IOS::openmode which_; +}; + +template +class filter_close_operation { +public: + typedef void result_type; + filter_close_operation(T& t, Sink& snk, BOOST_IOS::openmode which) + : t_(t), snk_(snk), which_(which) + { } + void operator()() const { boost::iostreams::close(t_, snk_, which_); } +private: + BOOST_DELETED_FUNCTION(filter_close_operation& operator=(const filter_close_operation&)) + T& t_; + Sink& snk_; + BOOST_IOS::openmode which_; +}; + +template +device_close_operation +call_close(T& t, BOOST_IOS::openmode which) +{ return device_close_operation(t, which); } + +template +filter_close_operation +call_close(T& t, Sink& snk, BOOST_IOS::openmode which) +{ return filter_close_operation(t, snk, which); } + + // Function objects and object generators for invoking + // boost::iostreams::detail::close_all + +template +class device_close_all_operation { +public: + typedef void result_type; + device_close_all_operation(T& t) : t_(t) { } + void operator()() const { detail::close_all(t_); } +private: + BOOST_DELETED_FUNCTION(device_close_all_operation& operator=(const device_close_all_operation&)) + T& t_; +}; + +template +class filter_close_all_operation { +public: + typedef void result_type; + filter_close_all_operation(T& t, Sink& snk) : t_(t), snk_(snk) { } + void operator()() const { detail::close_all(t_, snk_); } +private: + BOOST_DELETED_FUNCTION(filter_close_all_operation& operator=(const filter_close_all_operation&)) + T& t_; + Sink& snk_; +}; + +template +device_close_all_operation call_close_all(T& t) +{ return device_close_all_operation(t); } + +template +filter_close_all_operation +call_close_all(T& t, Sink& snk) +{ return filter_close_all_operation(t, snk); } + + // Function object and object generator for invoking a + // member function void close(std::ios_base::openmode) + +template +class member_close_operation { +public: + typedef void result_type; + member_close_operation(T& t, BOOST_IOS::openmode which) + : t_(t), which_(which) + { } + void operator()() const { t_.close(which_); } +private: + BOOST_DELETED_FUNCTION(member_close_operation& operator=(const member_close_operation&)) + T& t_; + BOOST_IOS::openmode which_; +}; + +template +member_close_operation call_member_close(T& t, BOOST_IOS::openmode which) +{ return member_close_operation(t, which); } + + // Function object and object generator for invoking a + // member function void reset() + +template +class reset_operation { +public: + reset_operation(T& t) : t_(t) { } + void operator()() const { t_.reset(); } +private: + BOOST_DELETED_FUNCTION(reset_operation& operator=(const reset_operation&)) + T& t_; +}; + +template +reset_operation call_reset(T& t) { return reset_operation(t); } + + // Function object and object generator for clearing a flag + +template +class clear_flags_operation { +public: + typedef void result_type; + clear_flags_operation(T& t) : t_(t) { } + void operator()() const { t_ = 0; } +private: + BOOST_DELETED_FUNCTION(clear_flags_operation& operator=(const clear_flags_operation&)) + T& t_; +}; + +template +clear_flags_operation clear_flags(T& t) +{ return clear_flags_operation(t); } + + // Function object and generator for flushing a buffer + +// Function object for use with execute_all() +template +class flush_buffer_operation { +public: + typedef void result_type; + flush_buffer_operation(Buffer& buf, Device& dev, bool flush) + : buf_(buf), dev_(dev), flush_(flush) + { } + void operator()() const + { + if (flush_) + buf_.flush(dev_); + } +private: + BOOST_DELETED_FUNCTION(flush_buffer_operation& operator=(const flush_buffer_operation&)) + Buffer& buf_; + Device& dev_; + bool flush_; +}; + +template +flush_buffer_operation +flush_buffer(Buffer& buf, Device& dev, bool flush) +{ return flush_buffer_operation(buf, dev, flush); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED diff --git a/boost/iostreams/detail/ios.hpp b/boost/iostreams/detail/ios.hpp new file mode 100644 index 0000000..d09a2d6 --- /dev/null +++ b/boost/iostreams/detail/ios.hpp @@ -0,0 +1,65 @@ +// (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 BOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) +# include +# else +# include +# include +# endif +#else +# include +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// +# define BOOST_IOSTREAMS_BASIC_IOS(ch, tr) std::basic_ios< ch, tr > +# if !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) && \ + !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) \ + /**/ + +#define BOOST_IOS std::ios +#define BOOST_IOSTREAMS_FAILURE std::ios::failure + +# else + +#define BOOST_IOS std::ios_base +#define BOOST_IOSTREAMS_FAILURE std::ios_base::failure + +# endif +#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +#define BOOST_IOS std::ios +#define BOOST_IOSTREAMS_BASIC_IOS(ch, tr) std::ios +#define BOOST_IOSTREAMS_FAILURE boost::iostreams::detail::failure + +class failure : std::exception { +public: + explicit failure(const std::string& what_arg) : what_(what_arg) { } + const char* what() const { return what_.c_str(); } +private: + std::string what_; +}; + +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------// + +} } } // End namespace failure, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IOS_HPP_INCLUDED diff --git a/boost/iostreams/detail/iostream.hpp b/boost/iostreams/detail/iostream.hpp new file mode 100644 index 0000000..1e19f08 --- /dev/null +++ b/boost/iostreams/detail/iostream.hpp @@ -0,0 +1,34 @@ +// (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 BOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include +# include +#else +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::basic_istream< ch, tr > +# define BOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::basic_ostream< ch, tr > +# define BOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::basic_iostream< ch, tr > +#else +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf +# define BOOST_IOSTREAMS_BASIC_ISTREAM(ch, tr) std::istream +# define BOOST_IOSTREAMS_BASIC_OSTREAM(ch, tr) std::ostream +# define BOOST_IOSTREAMS_BASIC_IOSTREAM(ch, tr) std::iostream +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IOSTREAM_HPP_INCLUDED diff --git a/boost/iostreams/detail/is_dereferenceable.hpp b/boost/iostreams/detail/is_dereferenceable.hpp new file mode 100644 index 0000000..06744ab --- /dev/null +++ b/boost/iostreams/detail/is_dereferenceable.hpp @@ -0,0 +1,80 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-2007 Jonathan Turkanis +// (C) Copyright David Abrahams 2004. +// 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_IS_DEREFERENCEABLE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED + +# include +# include +# include +# include + +namespace boost { namespace iostreams { namespace detail { + +// is_dereferenceable metafunction +// +// Requires: Given x of type T&, if the expression *x is well-formed +// it must have complete type; otherwise, it must neither be ambiguous +// nor violate access. + +// This namespace ensures that ADL doesn't mess things up. +namespace is_dereferenceable_ +{ + // a type returned from operator* when no increment is found in the + // type's own namespace + struct tag {}; + + // any soaks up implicit conversions and makes the following + // operator* less-preferred than any other such operator that + // might be found via ADL. + struct any { template any(T const&); }; + + // This is a last-resort operator* for when none other is found + tag operator*(any const&); + +# if BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3202)) +# define BOOST_comma(a,b) (a) +# else + // In case an operator++ is found that returns void, we'll use ++x,0 + tag operator,(tag,int); +# define BOOST_comma(a,b) (a,b) +# endif + + // two check overloads help us identify which operator++ was picked + char (& check_increment(tag) )[2]; + + template + char check_increment(T const&); + + template + struct impl + { + static typename boost::remove_cv::type& x; + + BOOST_STATIC_CONSTANT( + bool + , value = sizeof(is_dereferenceable_::check_increment(BOOST_comma(*x,0))) == 1 + ); + }; +} + +# undef BOOST_comma + +template +struct is_dereferenceable + : public ::boost::integral_constant::value > +{ + BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_dereferenceable,(T)) +}; + +} } + + +} // End namespaces detail, iostreams, boost. + +#endif // BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED diff --git a/boost/iostreams/detail/is_iterator_range.hpp b/boost/iostreams/detail/is_iterator_range.hpp new file mode 100644 index 0000000..39d845f --- /dev/null +++ b/boost/iostreams/detail/is_iterator_range.hpp @@ -0,0 +1,34 @@ +// (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 BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED + +#include +#include +#include + +// Must come last. +#include + +namespace boost { + +// We avoid dependence on Boost.Range by using a forward declaration. +template +class iterator_range; + +namespace iostreams { + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iterator_range, boost::iterator_range, 1) + +} // End namespace iostreams. + +} // End namespace boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED diff --git a/boost/iostreams/detail/newline.hpp b/boost/iostreams/detail/newline.hpp new file mode 100644 index 0000000..d6fceb0 --- /dev/null +++ b/boost/iostreams/detail/newline.hpp @@ -0,0 +1,32 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +namespace boost { namespace iostreams { namespace detail { + +template +struct newline; + +template<> +struct newline { + BOOST_STATIC_CONSTANT(char, value = '\n'); +}; + +template<> +struct newline { + BOOST_STATIC_CONSTANT(wchar_t, value = L'\n'); +}; + +} } } // End namespaces detaill, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED diff --git a/boost/iostreams/detail/optional.hpp b/boost/iostreams/detail/optional.hpp new file mode 100644 index 0000000..7146e4c --- /dev/null +++ b/boost/iostreams/detail/optional.hpp @@ -0,0 +1,114 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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. + +// Recent changes to Boost.Optional involving assigment broke Boost.Iostreams, +// in a way which could be remedied only by relying on the deprecated reset +// functions; with VC6, even reset didn't work. Until this problem is +// understood, Iostreams will use a private version of optional with a smart +// pointer interface. + +#ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +// Taken from . +template +class aligned_storage +{ + // Borland ICEs if unnamed unions are used for this! + union dummy_u + { + char data[ sizeof(T) ]; + BOOST_DEDUCED_TYPENAME type_with_alignment< + ::boost::alignment_of::value >::type aligner_; + } dummy_ ; + + public: + + void const* address() const { return &dummy_.data[0]; } + void * address() { return &dummy_.data[0]; } +}; + +template +class optional { +public: + typedef T element_type; + optional() : initialized_(false) { } + optional(const T& t) : initialized_(false) { reset(t); } + ~optional() { reset(); } + T& operator*() + { + BOOST_ASSERT(initialized_); + return *static_cast(address()); + } + const T& operator*() const + { + BOOST_ASSERT(initialized_); + return *static_cast(address()); + } + T* operator->() + { + BOOST_ASSERT(initialized_); + return static_cast(address()); + } + const T* operator->() const + { + BOOST_ASSERT(initialized_); + return static_cast(address()); + } + T* get() + { + BOOST_ASSERT(initialized_); + return static_cast(address()); + } + const T* get() const + { + BOOST_ASSERT(initialized_); + return static_cast(address()); + } + void reset() + { + if (initialized_) { + #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(600)) \ + /**/ + T* t = static_cast(address()); + t->~T(); + #else + static_cast(address())->T::~T(); + #endif + initialized_ = false; + } + } + void reset(const T& t) + { + reset(); + new (address()) T(t); + initialized_ = true; + } +private: + optional(const optional&); + optional& operator=(const optional&); + void* address() { return &storage_; } + const void* address() const { return &storage_; } + aligned_storage storage_; + bool initialized_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED diff --git a/boost/iostreams/detail/param_type.hpp b/boost/iostreams/detail/param_type.hpp new file mode 100644 index 0000000..3a99493 --- /dev/null +++ b/boost/iostreams/detail/param_type.hpp @@ -0,0 +1,27 @@ +// (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 BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct param_type { + typedef typename mpl::if_, T&, const T&>::type type; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED //-----------// diff --git a/boost/iostreams/detail/path.hpp b/boost/iostreams/detail/path.hpp new file mode 100644 index 0000000..a5d1ad3 --- /dev/null +++ b/boost/iostreams/detail/path.hpp @@ -0,0 +1,214 @@ +/* + * 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. + * + * File: boost/iostreams/detail/path.hpp + * Date: Sat Jun 21 21:24:05 MDT 2008 + * Copyright: 2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the class boost::iostreams::detail::path, for storing a + * a std::string or std::wstring. + * + * This class allows interoperability with Boost.Filesystem without + * creating a dependence on Boost.Filesystem headers or implementation. + */ + +#ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED + +#include +#include +#include +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS +# include +#endif +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //------------------------------------// + +class path { + template + struct sfinae + { + typedef V type; + }; +public: + + // Default constructor + path() : narrow_(), wide_(), is_wide_(false) { } + + // Constructor taking a std::string + path(const std::string& p) : narrow_(p), wide_(), is_wide_(false) { } + + // Constructor taking a C-style string + path(const char* p) : narrow_(p), wide_(), is_wide_(false) { } + + // Constructor taking a boost::filesystem2::path or + // boost::filesystem2::wpath + template + explicit path(const Path& p, typename Path::external_string_type* = 0) + { + init(p.external_file_string()); + } + + // Constructor taking a boost::filesystem3::path (boost filesystem v3) + template + explicit path(const Path& p, typename Path::codecvt_type* = 0) + { + init(p.native()); + } + + // Copy constructor + path(const path& p) + : narrow_(p.narrow_), wide_(p.wide_), is_wide_(p.is_wide_) + { } + + // Assignment operator taking another path + path& operator=(const path& p) + { + narrow_ = p.narrow_; + wide_ = p.wide_; + is_wide_ = p.is_wide_; + return *this; + } + + // Assignment operator taking a std::string + path& operator=(const std::string& p) + { + narrow_ = p; + wide_.clear(); + is_wide_ = false; + return *this; + } + + // Assignment operator taking a C-style string + path& operator=(const char* p) + { + narrow_.assign(p); + wide_.clear(); + is_wide_ = false; + return *this; + } + +#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1400) + // Assignment operator taking a boost::filesystem2::path or + // boost::filesystem2::wpath + // (not on Visual C++ 7.1/8.0, as it seems to have problems with + // SFINAE functions with the same parameters, doesn't seem + // worth working around). + template + typename sfinae::type + operator=(const Path& p) + { + init(p.external_file_string()); + return *this; + } +#endif + + // Assignment operator taking a boost::filesystem3::path + template + typename sfinae::type + operator=(const Path& p) + { + init(p.native()); + return *this; + } + + bool is_wide() const { return is_wide_; } + + // Returns a representation of the underlying path as a std::string + // Requires: is_wide() returns false + const char* c_str() const { return narrow_.c_str(); } + + // Returns a representation of the underlying path as a std::wstring + // Requires: is_wide() returns true + const wchar_t* c_wstr() const { return wide_.c_str(); } +private: + + // For wide-character paths, use a boost::filesystem::wpath instead of a + // std::wstring + path(const std::wstring&); + path& operator=(const std::wstring&); + + void init(std::string const& file_path) + { + narrow_ = file_path; + wide_.clear(); + is_wide_ = false; + } + + void init(std::wstring const& file_path) + { + narrow_.clear(); + wide_ = file_path; + is_wide_ = true; + } + + std::string narrow_; + std::wstring wide_; + bool is_wide_; +}; + +inline bool operator==(const path& lhs, const path& rhs) +{ + return lhs.is_wide() ? + rhs.is_wide() && std::wcscmp(lhs.c_wstr(), rhs.c_wstr()) == 0 : + !rhs.is_wide() && std::strcmp(lhs.c_str(), rhs.c_str()) == 0; +} + +#else // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //---------------------------// + +class path { +public: + path() { } + path(const std::string& p) : path_(p) { } + path(const char* p) : path_(p) { } + template + path(const Path& p) : path_(p.external_file_string()) { } + path(const path& p) : path_(p.path_) { } + path& operator=(const path& other) + { + path_ = other.path_; + return *this; + } + path& operator=(const std::string& p) + { + path_ = p; + return *this; + } + path& operator=(const char* p) + { + path_ = p; + return *this; + } + template + path& operator=(const Path& p) + { + path_ = p.external_file_string(); + return *this; + } + bool is_wide() const { return false; } + const char* c_str() const { return path_.c_str(); } + const wchar_t* c_wstr() const { return 0; } +private: + std::string path_; +}; + +inline bool operator==(const path& lhs, const path& rhs) +{ + return std::strcmp(lhs.c_str(), rhs.c_str()) == 0 ; +} + +#endif // #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //--------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PATH_HPP_INCLUDED diff --git a/boost/iostreams/detail/push.hpp b/boost/iostreams/detail/push.hpp new file mode 100644 index 0000000..d66740e --- /dev/null +++ b/boost/iostreams/detail/push.hpp @@ -0,0 +1,153 @@ +// (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 BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// Macro: BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper). +// Description: Defines overloads with name 'name' which forward to a function +// 'helper' which takes a filter or devide by const reference. +// +#define BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name, mode, ch, helper) \ + BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 0, ?) \ + /**/ + +// +// Macro: BOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper). +// Description: Defines constructors which forward to a function +// 'helper' which takes a filter or device by const reference. +// +#define BOOST_IOSTREAMS_DEFINE_PUSH(name, mode, ch, helper) \ + BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, 1, void) \ + /**/ + +//--------------------Definition of BOOST_IOSTREAMS_DEFINE_PUSH_IMPL----------// + +#define BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, arg, helper, has_return) \ + this->helper( ::boost::iostreams::detail::resolve(arg) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); \ + /**/ + +#if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) \ + /**/ +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_streambuf& sb BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_istream& is BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_ostream& os BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(::std::basic_iostream& io BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const iterator_range& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_PP_EXPR_IF(has_return, return) \ + this->helper( ::boost::iostreams::detail::range_adapter< \ + mode, iterator_range \ + >(rng) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const ::boost::iostreams::pipeline& p) \ + { p.push(*this); } \ + template \ + BOOST_PP_IIF(has_return, result, explicit) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS() BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + /**/ +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::streambuf& sb BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::istream& is BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::ostream& os BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_STATIC_ASSERT((!is_convertible::value)); \ + BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \ + BOOST_PP_IF(has_return, result, explicit) \ + name(::std::iostream& io BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const iterator_range& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { BOOST_PP_EXPR_IF(has_return, return) \ + this->helper( ::boost::iostreams::detail::range_adapter< \ + mode, iterator_range \ + >(rng) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const ::boost::iostreams::pipeline& p) \ + { p.push(*this); } \ + template \ + BOOST_PP_EXPR_IF(has_return, result) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS() BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + /**/ +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +#else // #if VC6, VC7.0, Borland 5.x +# define BOOST_IOSTREAMS_DEFINE_PUSH_IMPL(name, mode, ch, helper, has_return, result) \ + template \ + void BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::mpl::true_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \ + { t.push(*this); } \ + template \ + void BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::mpl::false_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \ + { this->helper( ::boost::iostreams::detail::resolve(t) \ + BOOST_IOSTREAMS_PUSH_ARGS() ); } \ + template \ + BOOST_PP_IF(has_return, result, explicit) \ + name(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { \ + this->BOOST_PP_CAT(name, _msvc_impl) \ + ( ::boost::iostreams::detail::is_pipeline(), \ + t BOOST_IOSTREAMS_PUSH_ARGS() ); \ + } \ + /**/ +#endif // #if VC6, VC7.0, Borland 5.x + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED diff --git a/boost/iostreams/detail/push_params.hpp b/boost/iostreams/detail/push_params.hpp new file mode 100644 index 0000000..8d8e5d7 --- /dev/null +++ b/boost/iostreams/detail/push_params.hpp @@ -0,0 +1,21 @@ +// (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 BOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#define BOOST_IOSTREAMS_PUSH_PARAMS() \ + , std::streamsize buffer_size = -1 , std::streamsize pback_size = -1 \ + /**/ + +#define BOOST_IOSTREAMS_PUSH_ARGS() , buffer_size, pback_size + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PUSH_PARAMS_HPP_INCLUDED diff --git a/boost/iostreams/detail/resolve.hpp b/boost/iostreams/detail/resolve.hpp new file mode 100644 index 0000000..00d2442 --- /dev/null +++ b/boost/iostreams/detail/resolve.hpp @@ -0,0 +1,230 @@ +// (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 BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // partial spec, put size_t in std. +#include // std::size_t. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include // true_. +#include +#include +#include + +// Must come last. +#include // VC7.1 C4224. + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of resolve-------------------------------------// + +#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------// + +template +struct resolve_traits { + typedef typename + mpl::if_< + boost::detail::is_incrementable, + output_iterator_adapter, + const T& + >::type type; +}; + +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// + +template +typename resolve_traits::type +resolve( const T& t + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) + + // I suspect that the compilers which require this workaround may + // be correct, but I'm not sure why :( + #if BOOST_WORKAROUND(BOOST_INTEL_CXX_VERSION, BOOST_TESTED_AT(810)) ||\ + BOOST_WORKAROUND(__MWERKS__, BOOST_TESTED_AT(0x3205)) || \ + BOOST_WORKAROUND(BOOST_IOSTREAMS_GCC, BOOST_TESTED_AT(400)) ||\ + BOOST_WORKAROUND(__IBMCPP__, BOOST_TESTED_AT(1110)) + /**/ + , typename disable_if< is_iterator_range >::type* = 0 + #endif + ) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +mode_adapter< Mode, std::basic_streambuf > +resolve(std::basic_streambuf& sb) +{ return mode_adapter< Mode, std::basic_streambuf >(wrap(sb)); } + +template +mode_adapter< Mode, std::basic_istream > +resolve(std::basic_istream& is) +{ return mode_adapter< Mode, std::basic_istream >(wrap(is)); } + +template +mode_adapter< Mode, std::basic_ostream > +resolve(std::basic_ostream& os) +{ return mode_adapter< Mode, std::basic_ostream >(wrap(os)); } + +template +mode_adapter< Mode, std::basic_iostream > +resolve(std::basic_iostream& io) +{ return mode_adapter< Mode, std::basic_iostream >(wrap(io)); } + +template +array_adapter resolve(Ch (&array)[N]) +{ return array_adapter(array); } + +template +range_adapter< Mode, boost::iterator_range > +resolve(const boost::iterator_range& rng) +{ return range_adapter< Mode, boost::iterator_range >(rng); } + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// + +template +typename resolve_traits::type +resolve( const T& t + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) + #if defined(__GNUC__) + , typename disable_if< is_iterator_range >::type* = 0 + #endif + ) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +mode_adapter +resolve(std::streambuf& sb) +{ return mode_adapter(wrap(sb)); } + +template +mode_adapter +resolve(std::istream& is) +{ return mode_adapter(wrap(is)); } + +template +mode_adapter +resolve(std::ostream& os) +{ return mode_adapter(wrap(os)); } + +template +mode_adapter +resolve(std::iostream& io) +{ return mode_adapter(wrap(io)); } + +template +array_adapter resolve(Ch (&array)[N]) +{ return array_adapter(array); } + +template +range_adapter< Mode, boost::iterator_range > +resolve(const boost::iterator_range& rng) +{ return range_adapter< Mode, boost::iterator_range >(rng); } + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// +#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------// + +template +struct resolve_traits { + // Note: test for is_iterator_range must come before test for output + // iterator. + typedef typename + iostreams::select< // Disambiguation for Tru64. + is_std_io, + mode_adapter, + is_iterator_range, + range_adapter, + is_dereferenceable, + output_iterator_adapter, + is_array, + array_adapter, + else_, + #if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + const T& + #else + T + #endif + >::type type; +}; + +template +typename resolve_traits::type +resolve(const T& t, mpl::true_) +{ // Bad overload resolution. + typedef typename resolve_traits::type return_type; + return return_type(wrap(const_cast(t))); +} + +template +typename resolve_traits::type +resolve(const T& t, mpl::false_) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +typename resolve_traits::type +resolve(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) +{ return resolve(t, is_std_io()); } + +# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \ + !defined(__GNUC__) // ---------------------------------------------------// + +template +typename resolve_traits::type +resolve(T& t, mpl::true_) +{ + typedef typename resolve_traits::type return_type; + return return_type(wrap(t)); +} + +template +typename resolve_traits::type +resolve(T& t, mpl::false_) +{ + typedef typename resolve_traits::type return_type; + return return_type(t); +} + +template +typename resolve_traits::type +resolve(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) +{ return resolve(t, is_std_io()); } + +# endif // Borland 5.x or GCC //--------------------------------// +#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // VC7.1 4224. + +#endif // BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED diff --git a/boost/iostreams/detail/restrict_impl.hpp b/boost/iostreams/detail/restrict_impl.hpp new file mode 100644 index 0000000..7f09c24 --- /dev/null +++ b/boost/iostreams/detail/restrict_impl.hpp @@ -0,0 +1,483 @@ +/* + * 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. + + * File: boost/iostreams/detail/restrict_impl.hpp + * Date: Sun Jan 06 12:57:30 MST 2008 + * Copyright: 2007-2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * If included with the macro BOOST_IOSTREAMS_RESTRICT undefined, defines the + * class template boost::iostreams::restriction. If included with the macro + * BOOST_IOSTREAMS_RESTRICT defined as an identifier, defines the overloaded + * function template boost::iostreams::BOOST_IOSTREAMS_RESTRICT, and object + * generator for boost::iostreams::restriction. + * + * This design allows and + * to share an implementation. + */ + +#if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) && \ + !defined(BOOST_IOSTREAMS_RESTRICT) +# define BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED + +//------------------Implementation of restriction-----------------------------// + +# include // min. +# include // pair. +# include // intmax_t. +# include // DEDUCED_TYPENAME. +# include +# include +# include +# include +# include +# include +# include +# include // failure. +# include +# include +# include +# include // mode_of, is_direct. +# include +# include +# include +# include + +# include + +namespace boost { namespace iostreams { + +namespace detail { + +// +// Template name: restricted_indirect_device. +// Description: Provides an restricted view of an indirect Device. +// Template parameters: +// Device - An indirect model of Device that models either Source or +// SeekableDevice. +// +template +class restricted_indirect_device : public device_adapter { +private: + typedef typename detail::param_type::type param_type; +public: + typedef typename char_type_of::type char_type; + typedef typename mode_of::type mode; + BOOST_STATIC_ASSERT(!(is_convertible::value)); + struct category + : mode, + device_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + restricted_indirect_device( param_type dev, stream_offset off, + stream_offset len = -1 ); + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); +private: + stream_offset beg_, pos_, end_; +}; + +// +// Template name: restricted_direct_device. +// Description: Provides an restricted view of a Direct Device. +// Template parameters: +// Device - A model of Direct and Device. +// +template +class restricted_direct_device : public device_adapter { +public: + typedef typename char_type_of::type char_type; + typedef std::pair pair_type; + typedef typename mode_of::type mode; + BOOST_STATIC_ASSERT(!(is_convertible::value)); + struct category + : mode_of::type, + device_tag, + direct_tag, + closable_tag, + localizable_tag + { }; + restricted_direct_device( const Device& dev, stream_offset off, + stream_offset len = -1 ); + pair_type input_sequence(); + pair_type output_sequence(); +private: + pair_type sequence(mpl::true_); + pair_type sequence(mpl::false_); + char_type *beg_, *end_; +}; + +// +// Template name: restricted_filter. +// Description: Provides an restricted view of a Filter. +// Template parameters: +// Filter - An indirect model of Filter. +// +template +class restricted_filter : public filter_adapter { +public: + typedef typename char_type_of::type char_type; + typedef typename mode_of::type mode; + BOOST_STATIC_ASSERT(!(is_convertible::value)); + struct category + : mode, + filter_tag, + multichar_tag, + closable_tag, + localizable_tag, + optimally_buffered_tag + { }; + restricted_filter( const Filter& flt, stream_offset off, + stream_offset len = -1 ); + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + if (!open_) + open(src, BOOST_IOS::in); + std::streamsize amt = + end_ != -1 ? + (std::min) (n, static_cast(end_ - pos_)) : + n; + std::streamsize result = + iostreams::read(this->component(), src, s, amt); + if (result != -1) + pos_ += result; + return result; + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + if (!open_) + open(snk, BOOST_IOS::out); + if (end_ != -1 && pos_ + n >= end_) { + if(pos_ < end_) + pos_ += iostreams::write(this->component(), + snk, s, end_ - pos_); + boost::throw_exception(bad_write()); + } + std::streamsize result = + iostreams::write(this->component(), snk, s, n); + pos_ += result; + return result; + } + + template + std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way) + { + stream_offset next; + if (way == BOOST_IOS::beg) { + next = beg_ + off; + } else if (way == BOOST_IOS::cur) { + next = pos_ + off; + } else if (end_ != -1) { + next = end_ + off; + } else { + // Restriction is half-open; seek relative to the actual end. + pos_ = this->component().seek(dev, off, BOOST_IOS::end); + if (pos_ < beg_) + boost::throw_exception(bad_seek()); + return offset_to_position(pos_ - beg_); + } + if (next < beg_ || (end_ != -1 && next >= end_)) + boost::throw_exception(bad_seek()); + pos_ = this->component().seek(dev, next, BOOST_IOS::cur); + return offset_to_position(pos_ - beg_); + } + + template + void close(Device& dev) + { + open_ = false; + detail::close_all(this->component(), dev); + } + + template + void close(Device& dev, BOOST_IOS::openmode which) + { + open_ = false; + iostreams::close(this->component(), dev, which); + } +private: + template + void open(Device& dev, BOOST_IOS::openmode which) + { + typedef typename is_convertible::type is_dual_use; + open_ = true; + which = is_dual_use() ? which : (BOOST_IOS::in | BOOST_IOS::out); + iostreams::skip(this->component(), dev, beg_, which); + } + + stream_offset beg_, pos_, end_; + bool open_; +}; + +template +struct restriction_traits + : iostreams::select< // Disambiguation for Tru64. + is_filter, restricted_filter, + is_direct, restricted_direct_device, + else_, restricted_indirect_device + > + { }; + +} // End namespace detail. + +template +struct restriction : public detail::restriction_traits::type { + typedef typename detail::param_type::type param_type; + typedef typename detail::restriction_traits::type base_type; + restriction(param_type t, stream_offset off, stream_offset len = -1) + : base_type(t, off, len) + { } +}; + +namespace detail { + +//--------------Implementation of restricted_indirect_device------------------// + +template +restricted_indirect_device::restricted_indirect_device + (param_type dev, stream_offset off, stream_offset len) + : device_adapter(dev), beg_(off), pos_(off), + end_(len != -1 ? off + len : -1) +{ + if (len < -1 || off < 0) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); + iostreams::skip(this->component(), off); +} + +template +inline std::streamsize restricted_indirect_device::read + (char_type* s, std::streamsize n) +{ + using namespace std; + std::streamsize amt = + end_ != -1 ? + (std::min) (n, static_cast(end_ - pos_)) : + n; + std::streamsize result = iostreams::read(this->component(), s, amt); + if (result != -1) + pos_ += result; + return result; +} + +template +inline std::streamsize restricted_indirect_device::write + (const char_type* s, std::streamsize n) +{ + if (end_ != -1 && pos_ + n >= end_) { + if(pos_ < end_) + pos_ += iostreams::write(this->component(), s, end_ - pos_); + boost::throw_exception(bad_write()); + } + std::streamsize result = iostreams::write(this->component(), s, n); + pos_ += result; + return result; +} + +template +std::streampos restricted_indirect_device::seek + (stream_offset off, BOOST_IOS::seekdir way) +{ + stream_offset next; + if (way == BOOST_IOS::beg) { + next = beg_ + off; + } else if (way == BOOST_IOS::cur) { + next = pos_ + off; + } else if (end_ != -1) { + next = end_ + off; + } else { + // Restriction is half-open; seek relative to the actual end. + pos_ = iostreams::seek(this->component(), off, BOOST_IOS::end); + if (pos_ < beg_) + boost::throw_exception(bad_seek()); + return offset_to_position(pos_ - beg_); + } + if (next < beg_ || (end_ != -1 && next > end_)) + boost::throw_exception(bad_seek()); + pos_ = iostreams::seek(this->component(), next - pos_, BOOST_IOS::cur); + return offset_to_position(pos_ - beg_); +} + +//--------------Implementation of restricted_direct_device--------------------// + +template +restricted_direct_device::restricted_direct_device + (const Device& dev, stream_offset off, stream_offset len) + : device_adapter(dev), beg_(0), end_(0) +{ + std::pair seq = + sequence(is_convertible()); + if ( off < 0 || len < -1 || + (len != -1 && off + len > seq.second - seq.first) ) + { + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); + } + beg_ = seq.first + off; + end_ = len != -1 ? + seq.first + off + len : + seq.second; +} + +template +typename restricted_direct_device::pair_type +restricted_direct_device::input_sequence() +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + return std::make_pair(beg_, end_); +} + +template +typename restricted_direct_device::pair_type +restricted_direct_device::output_sequence() +{ + BOOST_STATIC_ASSERT((is_convertible::value)); + return std::make_pair(beg_, end_); +} + +template +typename restricted_direct_device::pair_type +restricted_direct_device::sequence(mpl::true_) +{ return iostreams::input_sequence(this->component()); } + +template +typename restricted_direct_device::pair_type +restricted_direct_device::sequence(mpl::false_) +{ return iostreams::output_sequence(this->component()); } + +//--------------Implementation of restricted_filter---------------------------// + +template +restricted_filter::restricted_filter + (const Filter& flt, stream_offset off, stream_offset len) + : filter_adapter(flt), beg_(off), + pos_(off), end_(len != -1 ? off + len : -1), open_(false) +{ + if (len < -1 || off < 0) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); +} + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#elif defined(BOOST_IOSTREAMS_RESTRICT) + +namespace boost { namespace iostreams { + +//--------------Implementation of restrict/slice------------------------------// + +// Note: The following workarounds are patterned after resolve.hpp. It has not +// yet been confirmed that they are necessary. + +# ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //------------------------// +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //------------------------------// + +template +restriction +BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) +{ return restriction(t, off, len); } + +template +restriction< std::basic_streambuf > +BOOST_IOSTREAMS_RESTRICT( std::basic_streambuf& sb, stream_offset off, + stream_offset len = -1 ) +{ return restriction< std::basic_streambuf >(sb, off, len); } + +template +restriction< std::basic_istream > +BOOST_IOSTREAMS_RESTRICT + (std::basic_istream& is, stream_offset off, stream_offset len = -1) +{ return restriction< std::basic_istream >(is, off, len); } + +template +restriction< std::basic_ostream > +BOOST_IOSTREAMS_RESTRICT + (std::basic_ostream& os, stream_offset off, stream_offset len = -1) +{ return restriction< std::basic_ostream >(os, off, len); } + +template +restriction< std::basic_iostream > +BOOST_IOSTREAMS_RESTRICT + (std::basic_iostream& io, stream_offset off, stream_offset len = -1) +{ return restriction< std::basic_iostream >(io, off, len); } + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// + +template +restriction +BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) +{ return restriction(t, off, len); } + +restriction +BOOST_IOSTREAMS_RESTRICT + (std::streambuf& sb, stream_offset off, stream_offset len = -1) +{ return restriction(sb, off, len); } + +restriction +BOOST_IOSTREAMS_RESTRICT + (std::istream& is, stream_offset off, stream_offset len = -1) +{ return restriction(is, off, len); } + +restriction +BOOST_IOSTREAMS_RESTRICT + (std::ostream& os, stream_offset off, stream_offset len = -1) +{ return restriction(os, off, len); } + +restriction +BOOST_IOSTREAMS_RESTRICT + (std::iostream& io, stream_offset off, stream_offset len = -1) +{ return restriction(io, off, len); } + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------// +# else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------// + +template +restriction +BOOST_IOSTREAMS_RESTRICT + (const T& t, stream_offset off, stream_offset len, mpl::true_) +{ // Bad overload resolution. + return restriction(const_cast(t, off, len)); +} + +template +restriction +BOOST_IOSTREAMS_RESTRICT + (const T& t, stream_offset off, stream_offset len, mpl::false_) +{ return restriction(t, off, len); } + +template +restriction +BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1 + BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) ) +{ return BOOST_IOSTREAMS_RESTRICT(t, off, len, is_std_io()); } + +# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \ + !defined(__GNUC__) // ---------------------------------------------------// + +template +restriction +BOOST_IOSTREAMS_RESTRICT(T& t, stream_offset off, stream_offset len = -1) +{ return restriction(t, off, len); } + +# endif // Borland 5.x or GCC //-------------------------------// +# endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------// + +} } // End namespaces iostreams, boost. + +# include + +#endif // #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ... diff --git a/boost/iostreams/detail/select.hpp b/boost/iostreams/detail/select.hpp new file mode 100644 index 0000000..16c5973 --- /dev/null +++ b/boost/iostreams/detail/select.hpp @@ -0,0 +1,86 @@ +// (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. + +// Contains the metafunction select, which mimics the effect of a chain of +// nested mpl if_'s. +// +// ----------------------------------------------------------------------------- +// +// Usage: +// +// typedef typename select< +// case1, type1, +// case2, type2, +// ... +// true_, typen +// >::type selection; +// +// Here case1, case2, ... are models of MPL::IntegralConstant with value type +// bool, and n <= 12. + +#ifndef BOOST_IOSTREAMS_SELECT_HPP_INCLUDED +#define BOOST_IOSTREAMS_SELECT_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +typedef mpl::true_ else_; + +template< typename Case1 = mpl::true_, + typename Type1 = mpl::void_, + typename Case2 = mpl::true_, + typename Type2 = mpl::void_, + typename Case3 = mpl::true_, + typename Type3 = mpl::void_, + typename Case4 = mpl::true_, + typename Type4 = mpl::void_, + typename Case5 = mpl::true_, + typename Type5 = mpl::void_, + typename Case6 = mpl::true_, + typename Type6 = mpl::void_, + typename Case7 = mpl::true_, + typename Type7 = mpl::void_, + typename Case8 = mpl::true_, + typename Type8 = mpl::void_, + typename Case9 = mpl::true_, + typename Type9 = mpl::void_, + typename Case10 = mpl::true_, + typename Type10 = mpl::void_, + typename Case11 = mpl::true_, + typename Type11 = mpl::void_, + typename Case12 = mpl::true_, + typename Type12 = mpl::void_ > +struct select { + typedef typename + mpl::eval_if< + Case1, mpl::identity, mpl::eval_if< + Case2, mpl::identity, mpl::eval_if< + Case3, mpl::identity, mpl::eval_if< + Case4, mpl::identity, mpl::eval_if< + Case5, mpl::identity, mpl::eval_if< + Case6, mpl::identity, mpl::eval_if< + Case7, mpl::identity, mpl::eval_if< + Case8, mpl::identity, mpl::eval_if< + Case9, mpl::identity, mpl::eval_if< + Case10, mpl::identity, mpl::eval_if< + Case11, mpl::identity, mpl::if_< + Case12, Type12, mpl::void_ > > > > > > > > > > > + >::type type; +}; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_SELECT_HPP_INCLUDED diff --git a/boost/iostreams/detail/select_by_size.hpp b/boost/iostreams/detail/select_by_size.hpp new file mode 100644 index 0000000..e08ca34 --- /dev/null +++ b/boost/iostreams/detail/select_by_size.hpp @@ -0,0 +1,161 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-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. + +// +// Intended as an alternative to type_traits::yes_type and type_traits::no_type. +// Provides an arbitrary number of types (case_<0>, case_<1>, ...) for +// determining the results of overload resultion using 'sizeof', plus a uniform +// means of using the result. yes_type and no_type are typedefs for case_<1> +// and case_<0>. A single case with negative argument, case_<-1>, is also +// provided, for convenience. +// +// This header may be included any number of times, with +// BOOST_SELECT_BY_SIZE_MAX_CASE defined to be the largest N such that case_ +// is needed for a particular application. It defaults to 20. +// +// This header depends only on Boost.Config and Boost.Preprocessor. Dependence +// on Type Traits or MPL was intentionally avoided, to leave open the +// possibility that select_by_size could be used by these libraries. +// +// Example usage: +// +// #define BOOST_SELECT_BY_SIZE_MAX_CASE 7 // (Needed when default was 2) +// #include +// +// using namespace boost::utility; +// +// case_<0> helper(bool); +// case_<1> helper(int); +// case_<2> helper(unsigned); +// case_<3> helper(long); +// case_<4> helper(unsigned long); +// case_<5> helper(float); +// case_<6> helper(double); +// case_<7> helper(const char*); +// +// struct test { +// static const int value = +// select_by_size< sizeof(helper(9876UL)) >::value; +// BOOST_STATIC_ASSERT(value == 4); +// }; +// +// For compilers with integral constant expression problems, e.g. Borland 5.x, +// one can also write +// +// struct test { +// BOOST_SELECT_BY_SIZE(int, value, helper(9876UL)); +// }; +// +// to define a static integral constant 'value' equal to +// +// select_by_size< sizeof(helper(9876UL)) >::value. +// + +// Include guards surround all contents of this header except for explicit +// specializations of select_by_size for case_ with N > 2. + +#ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED + +// The lowest N for which select_by_size< sizeof(case_) > has not been +// specialized. +#define SELECT_BY_SIZE_MAX_SPECIALIZED 20 + +#include // BOOST_STATIC_CONSTANT. +#include +#include + +/* Alternative implementation using max_align. + +#include +#include + +namespace boost { namespace utility { + +template +struct case_ { char c[(N + 1) * alignment_of::value]; }; + +template +struct select_by_size { + BOOST_STATIC_CONSTANT(int, value = + (Size / alignment_of::value - 1)); +}; + +} } // End namespaces utility, boost. + +*/ // End alternate implementation. + +namespace boost { namespace iostreams { namespace detail { + +//--------------Definition of case_-------------------------------------------// + +template struct case_ { char c1; case_ c2; }; +template<> struct case_<-1> { char c; }; +typedef case_ yes_type; +typedef case_ no_type; + +//--------------Declaration of select_by_size---------------------------------// + +template struct select_by_size; + +} } } // End namespaces detail, iostreams, boost. + +//--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------// + +// Sepecializes select_by_size for sizeof(case). The decrement is used +// here because the preprocessor library doesn't handle negative integers. +#define SELECT_BY_SIZE_SPEC(n) \ + namespace boost { namespace iostreams { namespace detail { \ + static const int BOOST_PP_CAT(sizeof_case_, n) = sizeof(case_); \ + template<> \ + struct select_by_size< BOOST_PP_CAT(sizeof_case_, n) > { \ + struct type { BOOST_STATIC_CONSTANT(int, value = n - 1); }; \ + BOOST_STATIC_CONSTANT(int, value = type::value); \ + }; \ + } } } \ + /**/ + +//--------------Default specializations of select_by_size---------------------// + +#define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n) +#define BOOST_PP_LOCAL_LIMITS (0, 20) +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO + +//--------------Definition of SELECT_BY_SIZE----------------------------------// + +#define BOOST_SELECT_BY_SIZE(type_, name, expr) \ + BOOST_STATIC_CONSTANT( \ + unsigned, \ + BOOST_PP_CAT(boost_select_by_size_temp_, name) = sizeof(expr) \ + ); \ + BOOST_STATIC_CONSTANT( \ + type_, \ + name = \ + ( ::boost::iostreams::detail::select_by_size< \ + BOOST_PP_CAT(boost_select_by_size_temp_, name) \ + >::value ) \ + ) \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_SELECT_BY_SIZE_HPP_INCLUDED + +//----------Specializations of SELECT_BY_SIZE (outside main inclued guards)---// + +#if defined(BOOST_SELECT_BY_SIZE_MAX_CASE) && \ + BOOST_SELECT_BY_SIZE_MAX_CASE > SELECT_BY_SIZE_MAX_SPECIALIZED + +#define BOOST_PP_LOCAL_MACRO(n) SELECT_BY_SIZE_SPEC(n) +#define BOOST_PP_LOCAL_LIMITS \ + (SELECT_BY_SIZE_MAX_SPECIALIZED, BOOST_SELECT_BY_SIZE_MAX_CASE) \ + /**/ +#include BOOST_PP_LOCAL_ITERATE() +#undef BOOST_PP_LOCAL_MACRO +#undef SELECT_BY_SIZE_MAX_SPECIALIZED +#define SELECT_BY_SIZE_MAX_SPECIALIZED BOOST_SELECT_BY_SIZE_MAX_CASE + +#endif diff --git a/boost/iostreams/detail/streambuf.hpp b/boost/iostreams/detail/streambuf.hpp new file mode 100644 index 0000000..f2e8081 --- /dev/null +++ b/boost/iostreams/detail/streambuf.hpp @@ -0,0 +1,34 @@ +// (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 BOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# include +#else +# include +#endif + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::basic_streambuf< ch, tr > +# define BOOST_IOSTREAMS_PUBSYNC pubsync +# define BOOST_IOSTREAMS_PUBSEEKOFF pubseekoff +# define BOOST_IOSTREAMS_PUBSEEKPOS pubseekpos +#else +# define BOOST_IOSTREAMS_BASIC_STREAMBUF(ch, tr) std::streambuf +# define BOOST_IOSTREAMS_PUBSYNC sync +# define BOOST_IOSTREAMS_PUBSEEKOFF seekoff +# define BOOST_IOSTREAMS_PUBSEEKPOS seekpos +#endif + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/streambuf/chainbuf.hpp b/boost/iostreams/detail/streambuf/chainbuf.hpp new file mode 100644 index 0000000..c3714fe --- /dev/null +++ b/boost/iostreams/detail/streambuf/chainbuf.hpp @@ -0,0 +1,113 @@ +// (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 BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC, template friends. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +//--------------Definition of chainbuf----------------------------------------// + +// +// Template name: chainbuf. +// Description: Stream buffer which operates by delegating to the first +// linked_streambuf in a chain. +// Template parameters: +// Chain - The chain type. +// +template +class chainbuf + : public BOOST_IOSTREAMS_BASIC_STREAMBUF( + typename Chain::char_type, + typename Chain::traits_type + ), + public access_control, + private noncopyable +{ +private: + typedef access_control, Access> client_type; +public: + typedef typename Chain::char_type char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(typename Chain::traits_type) +protected: + typedef linked_streambuf delegate_type; + chainbuf() { client_type::set_chain(&chain_); } + int_type underflow() + { sentry t(this); return translate(delegate().underflow()); } + int_type pbackfail(int_type c) + { sentry t(this); return translate(delegate().pbackfail(c)); } + std::streamsize xsgetn(char_type* s, std::streamsize n) + { sentry t(this); return delegate().xsgetn(s, n); } + int_type overflow(int_type c) + { sentry t(this); return translate(delegate().overflow(c)); } + std::streamsize xsputn(const char_type* s, std::streamsize n) + { sentry t(this); return delegate().xsputn(s, n); } + int sync() { sentry t(this); return delegate().sync(); } + pos_type seekoff( off_type off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { sentry t(this); return delegate().seekoff(off, way, which); } + pos_type seekpos( pos_type sp, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ) + { sentry t(this); return delegate().seekpos(sp, which); } +protected: + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF( + typename Chain::char_type, + typename Chain::traits_type + ) base_type; +private: + + // Translate from std int_type to chain's int_type. + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) std_traits; + typedef typename Chain::traits_type chain_traits; + static typename chain_traits::int_type + translate(typename std_traits::int_type c) + { return translate_int_type(c); } + + delegate_type& delegate() + { return static_cast(chain_.front()); } + void get_pointers() + { + this->setg(delegate().eback(), delegate().gptr(), delegate().egptr()); + this->setp(delegate().pbase(), delegate().epptr()); + this->pbump((int) (delegate().pptr() - delegate().pbase())); + } + void set_pointers() + { + delegate().setg(this->eback(), this->gptr(), this->egptr()); + delegate().setp(this->pbase(), this->epptr()); + delegate().pbump((int) (this->pptr() - this->pbase())); + } + struct sentry { + sentry(chainbuf* buf) : buf_(buf) + { buf_->set_pointers(); } + ~sentry() { buf_->get_pointers(); } + chainbuf* buf_; + }; + friend struct sentry; + Chain chain_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/streambuf/direct_streambuf.hpp b/boost/iostreams/detail/streambuf/direct_streambuf.hpp new file mode 100644 index 0000000..a55c462 --- /dev/null +++ b/boost/iostreams/detail/streambuf/direct_streambuf.hpp @@ -0,0 +1,311 @@ +// (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 BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include // pair. +#include // BOOST_DEDUCED_TYPENAME, +#include +#include // member template friends. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +namespace detail { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ) > +class direct_streambuf + : public linked_streambuf::type, Tr> +{ +public: + typedef typename char_type_of::type char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef linked_streambuf base_type; + typedef typename category_of::type category; + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF( + char_type, traits_type + ) streambuf_type; +public: // stream needs access. + void open(const T& t, std::streamsize buffer_size, + std::streamsize pback_size); + bool is_open() const; + void close(); + bool auto_close() const { return auto_close_; } + void set_auto_close(bool close) { auto_close_ = close; } + bool strict_sync() { return true; } + + // Declared in linked_streambuf. + T* component() { return storage_.get(); } +protected: + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type) + direct_streambuf(); + + //--------------Virtual functions-----------------------------------------// + + // Declared in linked_streambuf. + void close_impl(BOOST_IOS::openmode m); + const boost::core::typeinfo& component_type() const { return BOOST_CORE_TYPEID(T); } + void* component_impl() { return component(); } +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + public: +#endif + + // Declared in basic_streambuf. + int_type underflow(); + int_type pbackfail(int_type c); + int_type overflow(int_type c); + pos_type seekoff( off_type off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + pos_type seekpos(pos_type sp, BOOST_IOS::openmode which); +private: + pos_type seek_impl( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + void init_input(any_tag) { } + void init_input(input); + void init_output(any_tag) { } + void init_output(output); + void init_get_area(); + void init_put_area(); + bool one_head() const; + bool two_head() const; + optional storage_; + char_type *ibeg_, *iend_, *obeg_, *oend_; + bool auto_close_; +}; + +//------------------Implementation of direct_streambuf------------------------// + +template +direct_streambuf::direct_streambuf() + : ibeg_(0), iend_(0), obeg_(0), oend_(0), auto_close_(true) +{ this->set_true_eof(true); } + +template +void direct_streambuf::open + (const T& t, std::streamsize, std::streamsize) +{ + storage_.reset(t); + init_input(category()); + init_output(category()); + setg(0, 0, 0); + setp(0, 0); + this->set_needs_close(); +} + +template +bool direct_streambuf::is_open() const +{ return ibeg_ != 0 || obeg_ != 0; } + +template +void direct_streambuf::close() +{ + base_type* self = this; + detail::execute_all( detail::call_member_close(*self, BOOST_IOS::in), + detail::call_member_close(*self, BOOST_IOS::out), + detail::call_reset(storage_) ); +} + +template +typename direct_streambuf::int_type +direct_streambuf::underflow() +{ + if (!ibeg_) + boost::throw_exception(cant_read()); + if (!gptr()) + init_get_area(); + return gptr() != iend_ ? + traits_type::to_int_type(*gptr()) : + traits_type::eof(); +} + +template +typename direct_streambuf::int_type +direct_streambuf::pbackfail(int_type c) +{ + using namespace std; + if (!ibeg_) + boost::throw_exception(cant_read()); + if (gptr() != 0 && gptr() != ibeg_) { + gbump(-1); + if (!traits_type::eq_int_type(c, traits_type::eof())) + *gptr() = traits_type::to_char_type(c); + return traits_type::not_eof(c); + } + boost::throw_exception(bad_putback()); +} + +template +typename direct_streambuf::int_type +direct_streambuf::overflow(int_type c) +{ + using namespace std; + if (!obeg_) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("no write access")); + if (!pptr()) init_put_area(); + if (!traits_type::eq_int_type(c, traits_type::eof())) { + if (pptr() == oend_) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("write area exhausted") + ); + *pptr() = traits_type::to_char_type(c); + pbump(1); + return c; + } + return traits_type::not_eof(c); +} + +template +inline typename direct_streambuf::pos_type +direct_streambuf::seekoff + (off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return seek_impl(off, way, which); } + +template +inline typename direct_streambuf::pos_type +direct_streambuf::seekpos + (pos_type sp, BOOST_IOS::openmode which) +{ + return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); +} + +template +void direct_streambuf::close_impl(BOOST_IOS::openmode which) +{ + if (which == BOOST_IOS::in && ibeg_ != 0) { + setg(0, 0, 0); + ibeg_ = iend_ = 0; + } + if (which == BOOST_IOS::out && obeg_ != 0) { + sync(); + setp(0, 0); + obeg_ = oend_ = 0; + } + boost::iostreams::close(*storage_, which); +} + +template +typename direct_streambuf::pos_type direct_streambuf::seek_impl + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ + using namespace std; + BOOST_IOS::openmode both = BOOST_IOS::in | BOOST_IOS::out; + if (two_head() && (which & both) == both) + boost::throw_exception(bad_seek()); + stream_offset result = -1; + bool one = one_head(); + if (one && (pptr() != 0 || gptr()== 0)) + init_get_area(); // Switch to input mode, for code reuse. + if (one || ((which & BOOST_IOS::in) != 0 && ibeg_ != 0)) { + if (!gptr()) setg(ibeg_, ibeg_, iend_); + ptrdiff_t next = 0; + switch (way) { + case BOOST_IOS::beg: next = off; break; + case BOOST_IOS::cur: next = (gptr() - ibeg_) + off; break; + case BOOST_IOS::end: next = (iend_ - ibeg_) + off; break; + default: BOOST_ASSERT(0); + } + if (next < 0 || next > (iend_ - ibeg_)) + boost::throw_exception(bad_seek()); + setg(ibeg_, ibeg_ + next, iend_); + result = next; + } + if (!one && (which & BOOST_IOS::out) != 0 && obeg_ != 0) { + if (!pptr()) setp(obeg_, oend_); + ptrdiff_t next = 0; + switch (way) { + case BOOST_IOS::beg: next = off; break; + case BOOST_IOS::cur: next = (pptr() - obeg_) + off; break; + case BOOST_IOS::end: next = (oend_ - obeg_) + off; break; + default: BOOST_ASSERT(0); + } + if (next < 0 || next > (oend_ - obeg_)) + boost::throw_exception(bad_seek()); + pbump(static_cast(next - (pptr() - obeg_))); + result = next; + } + return offset_to_position(result); +} + +template +void direct_streambuf::init_input(input) +{ + std::pair p = input_sequence(*storage_); + ibeg_ = p.first; + iend_ = p.second; +} + +template +void direct_streambuf::init_output(output) +{ + std::pair p = output_sequence(*storage_); + obeg_ = p.first; + oend_ = p.second; +} + +template +void direct_streambuf::init_get_area() +{ + setg(ibeg_, ibeg_, iend_); + if (one_head() && pptr()) { + gbump(static_cast(pptr() - obeg_)); + setp(0, 0); + } +} + +template +void direct_streambuf::init_put_area() +{ + setp(obeg_, oend_); + if (one_head() && gptr()) { + pbump(static_cast(gptr() - ibeg_)); + setg(0, 0, 0); + } +} + +template +inline bool direct_streambuf::one_head() const +{ return ibeg_ && obeg_ && ibeg_ == obeg_; } + +template +inline bool direct_streambuf::two_head() const +{ return ibeg_ && obeg_ && ibeg_ != obeg_; } + +//----------------------------------------------------------------------------// + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include // MSVC + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/streambuf/indirect_streambuf.hpp b/boost/iostreams/detail/streambuf/indirect_streambuf.hpp new file mode 100644 index 0000000..9f159a3 --- /dev/null +++ b/boost/iostreams/detail/streambuf/indirect_streambuf.hpp @@ -0,0 +1,454 @@ +// (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. + +// This material is heavily indebted to the discussion and code samples in +// A. Langer and K. Kreft, "Standard C++ IOStreams and Locales", +// Addison-Wesley, 2000, pp. 228-43. + +// User "GMSB" provided an optimization for small seeks. + +#ifndef BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED + +#include // min, max. +#include +#include +#include // Member template friends. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC, BCC 5.x + +namespace boost { namespace iostreams { namespace detail { + +// +// Description: The implementation of basic_streambuf used by chains. +// +template +class indirect_streambuf + : public linked_streambuf::type, Tr> +{ +public: + typedef typename char_type_of::type char_type; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename category_of::type category; + typedef concept_adapter wrapper; + typedef detail::basic_buffer buffer_type; + typedef indirect_streambuf my_type; + typedef detail::linked_streambuf base_type; + typedef linked_streambuf streambuf_type; +public: + indirect_streambuf(); + + void open(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()); + bool is_open() const; + void close(); + bool auto_close() const; + void set_auto_close(bool close); + bool strict_sync(); + + // Declared in linked_streambuf. + T* component() { return &*obj(); } +protected: + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base_type) + + //----------virtual functions---------------------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE + void imbue(const std::locale& loc); +#endif +#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + public: +#endif + int_type underflow(); + int_type pbackfail(int_type c); + int_type overflow(int_type c); + int sync(); + pos_type seekoff( off_type off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + pos_type seekpos(pos_type sp, BOOST_IOS::openmode which); + + // Declared in linked_streambuf. + void set_next(streambuf_type* next); + void close_impl(BOOST_IOS::openmode m); + const boost::core::typeinfo& component_type() const { return BOOST_CORE_TYPEID(T); } + void* component_impl() { return component(); } +private: + + //----------Accessor functions--------------------------------------------// + + wrapper& obj() { return *storage_; } + streambuf_type* next() const { return next_; } + buffer_type& in() { return buffer_.first(); } + buffer_type& out() { return buffer_.second(); } + bool can_read() const { return is_convertible::value; } + bool can_write() const { return is_convertible::value; } + bool output_buffered() const { return (flags_ & f_output_buffered) != 0; } + bool shared_buffer() const { return is_convertible::value || is_convertible::value; } + void set_flags(int f) { flags_ = f; } + + //----------State changing functions--------------------------------------// + + virtual void init_get_area(); + virtual void init_put_area(); + + //----------Utility function----------------------------------------------// + + pos_type seek_impl( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ); + void sync_impl(); + + enum flag_type { + f_open = 1, + f_output_buffered = f_open << 1, + f_auto_close = f_output_buffered << 1 + }; + + optional storage_; + streambuf_type* next_; + double_object< + buffer_type, + is_convertible< + Mode, + two_sequence + > + > buffer_; + std::streamsize pback_size_; + int flags_; +}; + +//--------------Implementation of indirect_streambuf--------------------------// + +template +indirect_streambuf::indirect_streambuf() + : next_(0), pback_size_(0), flags_(f_auto_close) { } + +//--------------Implementation of open, is_open and close---------------------// + +template +void indirect_streambuf::open + (const T& t, std::streamsize buffer_size, std::streamsize pback_size) +{ + using namespace std; + + // Normalize buffer sizes. + buffer_size = + (buffer_size != -1) ? + buffer_size : + iostreams::optimal_buffer_size(t); + pback_size = + (pback_size != -1) ? + pback_size : + default_pback_buffer_size; + + // Construct input buffer. + if (can_read()) { + pback_size_ = (std::max)(std::streamsize(2), pback_size); // STLPort needs 2. + std::streamsize size = + pback_size_ + + ( buffer_size ? buffer_size: std::streamsize(1) ); + in().resize(static_cast(size)); + if (!shared_buffer()) + init_get_area(); + } + + // Construct output buffer. + if (can_write() && !shared_buffer()) { + if (buffer_size != std::streamsize(0)) + out().resize(static_cast(buffer_size)); + init_put_area(); + } + + storage_.reset(wrapper(t)); + flags_ |= f_open; + if (can_write() && buffer_size > 1) + flags_ |= f_output_buffered; + this->set_true_eof(false); + this->set_needs_close(); +} + +template +inline bool indirect_streambuf::is_open() const +{ return (flags_ & f_open) != 0; } + +template +void indirect_streambuf::close() +{ + using namespace std; + base_type* self = this; + detail::execute_all( + detail::call_member_close(*self, BOOST_IOS::in), + detail::call_member_close(*self, BOOST_IOS::out), + detail::call_reset(storage_), + detail::clear_flags(flags_) + ); +} + +template +bool indirect_streambuf::auto_close() const +{ return (flags_ & f_auto_close) != 0; } + +template +void indirect_streambuf::set_auto_close(bool close) +{ flags_ = (flags_ & ~f_auto_close) | (close ? f_auto_close : 0); } + +//--------------Implementation virtual functions------------------------------// + +#ifndef BOOST_IOSTREAMS_NO_LOCALE +template +void indirect_streambuf::imbue(const std::locale& loc) +{ + if (is_open()) { + obj().imbue(loc); + if (next_) + next_->pubimbue(loc); + } +} +#endif + +template +typename indirect_streambuf::int_type +indirect_streambuf::underflow() +{ + using namespace std; + if (!gptr()) init_get_area(); + buffer_type& buf = in(); + if (gptr() < egptr()) return traits_type::to_int_type(*gptr()); + + // Fill putback buffer. + std::streamsize keep = + (std::min)( static_cast(gptr() - eback()), + pback_size_ ); + if (keep) + traits_type::move( buf.data() + (pback_size_ - keep), + gptr() - keep, keep ); + + // Set pointers to reasonable values in case read throws. + setg( buf.data() + pback_size_ - keep, + buf.data() + pback_size_, + buf.data() + pback_size_ ); + + // Read from source. + std::streamsize chars = + obj().read(buf.data() + pback_size_, buf.size() - pback_size_, next_); + if (chars == -1) { + this->set_true_eof(true); + chars = 0; + } + setg(eback(), gptr(), buf.data() + pback_size_ + chars); + return chars != 0 ? + traits_type::to_int_type(*gptr()) : + traits_type::eof(); +} + +template +typename indirect_streambuf::int_type +indirect_streambuf::pbackfail(int_type c) +{ + if (gptr() != eback()) { + gbump(-1); + if (!traits_type::eq_int_type(c, traits_type::eof())) + *gptr() = traits_type::to_char_type(c); + return traits_type::not_eof(c); + } else { + boost::throw_exception(bad_putback()); + } +} + +template +typename indirect_streambuf::int_type +indirect_streambuf::overflow(int_type c) +{ + if ( (output_buffered() && pptr() == 0) || + (shared_buffer() && gptr() != 0) ) + { + init_put_area(); + } + if (!traits_type::eq_int_type(c, traits_type::eof())) { + if (output_buffered()) { + if (pptr() == epptr()) { + sync_impl(); + if (pptr() == epptr()) + return traits_type::eof(); + } + *pptr() = traits_type::to_char_type(c); + pbump(1); + } else { + char_type d = traits_type::to_char_type(c); + if (obj().write(&d, 1, next_) != 1) + return traits_type::eof(); + } + } + return traits_type::not_eof(c); +} + +template +int indirect_streambuf::sync() +{ + try { // sync() is no-throw. + sync_impl(); + obj().flush(next_); + return 0; + } catch (...) { return -1; } +} + +template +bool indirect_streambuf::strict_sync() +{ + try { // sync() is no-throw. + sync_impl(); + return obj().flush(next_); + } catch (...) { return false; } +} + +template +inline typename indirect_streambuf::pos_type +indirect_streambuf::seekoff + (off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ return seek_impl(off, way, which); } + +template +inline typename indirect_streambuf::pos_type +indirect_streambuf::seekpos + (pos_type sp, BOOST_IOS::openmode which) +{ + return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which); +} + +template +typename indirect_streambuf::pos_type +indirect_streambuf::seek_impl + (stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which) +{ + if ( gptr() != 0 && way == BOOST_IOS::cur && which == BOOST_IOS::in && + eback() - gptr() <= off && off <= egptr() - gptr() ) + { // Small seek optimization + gbump(static_cast(off)); + return obj().seek(stream_offset(0), BOOST_IOS::cur, BOOST_IOS::in, next_) - + static_cast(egptr() - gptr()); + } + if (pptr() != 0) + this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6. + if (way == BOOST_IOS::cur && gptr()) + off -= static_cast(egptr() - gptr()); + bool two_head = is_convertible::value || + is_convertible::value; + if (two_head) { + BOOST_IOS::openmode both = BOOST_IOS::in | BOOST_IOS::out; + if ((which & both) == both) + boost::throw_exception(bad_seek()); + if (which & BOOST_IOS::in) { + setg(0, 0, 0); + } + if (which & BOOST_IOS::out) { + setp(0, 0); + } + } + else { + setg(0, 0, 0); + setp(0, 0); + } + return obj().seek(off, way, which, next_); +} + +template +inline void indirect_streambuf::set_next + (streambuf_type* next) +{ next_ = next; } + +template +inline void indirect_streambuf::close_impl + (BOOST_IOS::openmode which) +{ + if (which == BOOST_IOS::in && is_convertible::value) { + setg(0, 0, 0); + } + if (which == BOOST_IOS::out && is_convertible::value) { + sync(); + setp(0, 0); + } + #if defined(BOOST_MSVC) + #pragma warning(push) + #pragma warning(disable: 4127) // conditional expression is constant + #endif + if ( !is_convertible::value || + is_convertible::value == (which == BOOST_IOS::in) ) + { + obj().close(which, next_); + } + #if defined(BOOST_MSVC) + #pragma warning(pop) + #endif +} + +//----------State changing functions------------------------------------------// + +template +void indirect_streambuf::sync_impl() +{ + std::streamsize avail, amt; + if ((avail = static_cast(pptr() - pbase())) > 0) { + if ((amt = obj().write(pbase(), avail, next())) == avail) + setp(out().begin(), out().end()); + else { + const char_type* ptr = pptr(); + setp(out().begin() + amt, out().end()); + pbump(static_cast(ptr - pptr())); + } + } +} + +template +void indirect_streambuf::init_get_area() +{ + if (shared_buffer() && pptr() != 0) { + sync_impl(); + setp(0, 0); + } + setg(in().begin(), in().begin(), in().begin()); +} + +template +void indirect_streambuf::init_put_area() +{ + using namespace std; + if (shared_buffer() && gptr() != 0) { + obj().seek(static_cast(gptr() - egptr()), BOOST_IOS::cur, BOOST_IOS::in, next_); + setg(0, 0, 0); + } + if (output_buffered()) + setp(out().begin(), out().end()); + else + setp(0, 0); +} + +//----------------------------------------------------------------------------// + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC, BCC 5.x + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/streambuf/linked_streambuf.hpp b/boost/iostreams/detail/streambuf/linked_streambuf.hpp new file mode 100644 index 0000000..708c2c4 --- /dev/null +++ b/boost/iostreams/detail/streambuf/linked_streambuf.hpp @@ -0,0 +1,114 @@ +// (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 BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // member template friends. +#include +#include +#include // openmode. +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +template +class chain_base; + +template class chainbuf; + +#define BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base) \ + using base::eback; using base::gptr; using base::egptr; \ + using base::setg; using base::gbump; using base::pbase; \ + using base::pptr; using base::epptr; using base::setp; \ + using base::pbump; using base::underflow; using base::pbackfail; \ + using base::xsgetn; using base::overflow; using base::xsputn; \ + using base::sync; using base::seekoff; using base::seekpos; \ + /**/ + +template +class linked_streambuf : public BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) { +protected: + linked_streambuf() : flags_(0) { } + void set_true_eof(bool eof) + { + flags_ = (flags_ & ~f_true_eof) | (eof ? f_true_eof : 0); + } +public: + + // Should be called only after receiving an ordinary EOF indication, + // to confirm that it represents EOF rather than WOULD_BLOCK. + bool true_eof() const { return (flags_ & f_true_eof) != 0; } +protected: + + //----------grant friendship to chain_base and chainbuf-------------------// + +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + template< typename Self, typename ChT, typename TrT, + typename Alloc, typename Mode > + friend class chain_base; + template + friend class chainbuf; + template + friend class member_close_operation; +#else + public: + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, Tr) base; + BOOST_IOSTREAMS_USING_PROTECTED_STREAMBUF_MEMBERS(base) +#endif + void close(BOOST_IOS::openmode which) + { + if ( which == BOOST_IOS::in && + (flags_ & f_input_closed) == 0 ) + { + flags_ |= f_input_closed; + close_impl(which); + } + if ( which == BOOST_IOS::out && + (flags_ & f_output_closed) == 0 ) + { + flags_ |= f_output_closed; + close_impl(which); + } + } + void set_needs_close() + { + flags_ &= ~(f_input_closed | f_output_closed); + } + virtual void set_next(linked_streambuf* /* next */) { } + virtual void close_impl(BOOST_IOS::openmode) = 0; + virtual bool auto_close() const = 0; + virtual void set_auto_close(bool) = 0; + virtual bool strict_sync() = 0; + virtual const boost::core::typeinfo& component_type() const = 0; + virtual void* component_impl() = 0; +#ifndef BOOST_NO_MEMBER_TEMPLATE_FRIENDS + private: +#else + public: +#endif +private: + enum flag_type { + f_true_eof = 1, + f_input_closed = f_true_eof << 1, + f_output_closed = f_input_closed << 1 + }; + int flags_; +}; + +} } } // End namespaces detail, iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/detail/system_failure.hpp b/boost/iostreams/detail/system_failure.hpp new file mode 100644 index 0000000..10b291a --- /dev/null +++ b/boost/iostreams/detail/system_failure.hpp @@ -0,0 +1,84 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-2007 Jonathan Turkanis +// (C) Copyright Jonathan Graehl 2004. +// 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. + +// Used by mapped_file.cpp. + +#ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include // failure. + +#if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__) +namespace std { using ::strlen; } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS +# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +# include +#else +# include +# include +#endif + +namespace boost { namespace iostreams { namespace detail { + +inline BOOST_IOSTREAMS_FAILURE system_failure(const char* msg) +{ + std::string result; +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD err; + LPVOID lpMsgBuf; + if ( (err = ::GetLastError()) != NO_ERROR && + ::FormatMessageA( FORMAT_MESSAGE_ALLOCATE_BUFFER | + FORMAT_MESSAGE_FROM_SYSTEM, + NULL, + err, + MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), + (LPSTR) &lpMsgBuf, + 0, + NULL ) != 0 ) + { + result.reserve(std::strlen(msg) + 2 + std::strlen((LPSTR)lpMsgBuf)); + result.append(msg); + result.append(": "); + result.append((LPSTR) lpMsgBuf); + ::LocalFree(lpMsgBuf); + } else { + result += msg; + } +#else + const char* system_msg = errno ? strerror(errno) : ""; + result.reserve(std::strlen(msg) + 2 + std::strlen(system_msg)); + result.append(msg); + result.append(": "); + result.append(system_msg); +#endif + return BOOST_IOSTREAMS_FAILURE(result); +} + +inline BOOST_IOSTREAMS_FAILURE system_failure(const std::string& msg) +{ return system_failure(msg.c_str()); } + +inline void throw_system_failure(const char* msg) +{ boost::throw_exception(system_failure(msg)); } + +inline void throw_system_failure(const std::string& msg) +{ boost::throw_exception(system_failure(msg)); } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_SYSTEM_FAILURE_HPP_INCLUDED diff --git a/boost/iostreams/detail/template_params.hpp b/boost/iostreams/detail/template_params.hpp new file mode 100644 index 0000000..b07012f --- /dev/null +++ b/boost/iostreams/detail/template_params.hpp @@ -0,0 +1,26 @@ +// (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 BOOST_IOSTREAMS_DETAIL_TEMPLATE_PARAMS_HPP_INCLUDED + +#include +#include +#include + +#define BOOST_IOSTREAMS_TEMPLATE_PARAMS(arity, param) \ + BOOST_PP_EXPR_IF(arity, template<) \ + BOOST_PP_ENUM_PARAMS(arity, typename param) \ + BOOST_PP_EXPR_IF(arity, >) \ + /**/ + +#define BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, param) \ + BOOST_PP_EXPR_IF(arity, <) \ + BOOST_PP_ENUM_PARAMS(arity, param) \ + BOOST_PP_EXPR_IF(arity, >) \ + /**/ + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED diff --git a/boost/iostreams/detail/translate_int_type.hpp b/boost/iostreams/detail/translate_int_type.hpp new file mode 100644 index 0000000..ae48a2c --- /dev/null +++ b/boost/iostreams/detail/translate_int_type.hpp @@ -0,0 +1,62 @@ +// (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 BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct translate_int_type_impl; + +// +// Template name: translate_char. +// Description: Translates a character or an end-of-file indicator from the +// int_type of one character traits type to the int_type of another. +// +template +typename TargetTr::int_type +translate_int_type(typename SourceTr::int_type c) +{ + typedef translate_int_type_impl::value> impl; + return impl::template inner::translate(c); +} + +//----------------------------------------------------------------------------// + +template<> +struct translate_int_type_impl { + template + struct inner { + static typename TargetTr::int_type + translate(typename SourceTr::int_type c) { return c; } + }; +}; + +template<> +struct translate_int_type_impl { + template + struct inner { + static typename TargetTr::int_type + translate(typename SourceTr::int_type c) + { + return SourceTr::eq_int_type(SourceTr::eof()) ? + TargetTr::eof() : + TargetTr::to_int_type(SourceTr::to_char_type(c)); + } + }; +}; + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_TRANSLATE_INT_TYPE_HPP_INCLUDED diff --git a/boost/iostreams/detail/wrap_unwrap.hpp b/boost/iostreams/detail/wrap_unwrap.hpp new file mode 100644 index 0000000..f5f9789 --- /dev/null +++ b/boost/iostreams/detail/wrap_unwrap.hpp @@ -0,0 +1,98 @@ +// (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 BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED +#define BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // SFINAE, MSVC. +#include +#include +#include // is_std_io. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +//------------------Definition of wrap/unwrap traits--------------------------// + +template +struct wrapped_type + : mpl::if_, reference_wrapper, T> + { }; + +template +struct unwrapped_type + : unwrap_reference + { }; + +template +struct unwrap_ios + : mpl::eval_if< + is_std_io, + unwrap_reference, + mpl::identity + > + { }; + +//------------------Definition of wrap----------------------------------------// + +#ifndef BOOST_NO_SFINAE //----------------------------------------------------// + template + inline T wrap(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)) + { return t; } + + template + inline typename wrapped_type::type + wrap(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) { return boost::ref(t); } +#else // #ifndef BOOST_NO_SFINAE //-------------------------------------------// + template + inline typename wrapped_type::type // BCC 5.x needs namespace qualification. + wrap_impl(const T& t, mpl::true_) { return boost::ref(const_cast(t)); } + + template + inline typename wrapped_type::type // BCC 5.x needs namespace qualification. + wrap_impl(T& t, mpl::true_) { return boost::ref(t); } + + template + inline typename wrapped_type::type + wrap_impl(const T& t, mpl::false_) { return t; } + + template + inline typename wrapped_type::type + wrap_impl(T& t, mpl::false_) { return t; } + + template + inline typename wrapped_type::type + wrap(const T& t) { return wrap_impl(t, is_std_io()); } + + template + inline typename wrapped_type::type + wrap(T& t) { return wrap_impl(t, is_std_io()); } +#endif // #ifndef BOOST_NO_SFINAE //------------------------------------------// + +//------------------Definition of unwrap--------------------------------------// + +template +typename unwrapped_type::type& +unwrap(const reference_wrapper& ref) { return ref.get(); } + +template +typename unwrapped_type::type& unwrap(T& t) { return t; } + +template +const typename unwrapped_type::type& unwrap(const T& t) { return t; } + +} } } // End namespaces detail, iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED diff --git a/boost/iostreams/device/array.hpp b/boost/iostreams/device/array.hpp new file mode 100644 index 0000000..768a564 --- /dev/null +++ b/boost/iostreams/device/array.hpp @@ -0,0 +1,133 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-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 BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED +#define BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC, make sure size_t is in std. +#include +#include // std::size_t. +#include // pair. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +class array_adapter { +public: + typedef Ch char_type; + typedef std::pair pair_type; + struct category + : public Mode, + public device_tag, + public direct_tag + { }; + array_adapter(char_type* begin, char_type* end); + array_adapter(char_type* begin, std::size_t length); + array_adapter(const char_type* begin, const char_type* end); + array_adapter(const char_type* begin, std::size_t length); + template + array_adapter(char_type (&ar)[N]) + : begin_(ar), end_(ar + N) + { } + pair_type input_sequence(); + pair_type output_sequence(); +private: + char_type* begin_; + char_type* end_; +}; + +} // End namespace detail. + +#define BOOST_IOSTREAMS_ARRAY(name, mode) \ + template \ + struct BOOST_PP_CAT(basic_, name) : detail::array_adapter { \ + private: \ + typedef detail::array_adapter base_type; \ + public: \ + typedef typename base_type::char_type char_type; \ + typedef typename base_type::category category; \ + BOOST_PP_CAT(basic_, name)(char_type* begin, char_type* end) \ + : base_type(begin, end) { } \ + BOOST_PP_CAT(basic_, name)(char_type* begin, std::size_t length) \ + : base_type(begin, length) { } \ + BOOST_PP_CAT(basic_, name)(const char_type* begin, const char_type* end) \ + : base_type(begin, end) { } \ + BOOST_PP_CAT(basic_, name)(const char_type* begin, std::size_t length) \ + : base_type(begin, length) { } \ + template \ + BOOST_PP_CAT(basic_, name)(Ch (&ar)[N]) \ + : base_type(ar) { } \ + }; \ + typedef BOOST_PP_CAT(basic_, name) name; \ + typedef BOOST_PP_CAT(basic_, name) BOOST_PP_CAT(w, name); \ + /**/ +BOOST_IOSTREAMS_ARRAY(array_source, input_seekable) +BOOST_IOSTREAMS_ARRAY(array_sink, output_seekable) +BOOST_IOSTREAMS_ARRAY(array, seekable) +#undef BOOST_IOSTREAMS_ARRAY + + +//------------------Implementation of array_adapter---------------------------// + +namespace detail { + +template +array_adapter::array_adapter + (char_type* begin, char_type* end) + : begin_(begin), end_(end) + { } + +template +array_adapter::array_adapter + (char_type* begin, std::size_t length) + : begin_(begin), end_(begin + length) + { } + +template +array_adapter::array_adapter + (const char_type* begin, const char_type* end) + : begin_(const_cast(begin)), // Treated as read-only. + end_(const_cast(end)) // Treated as read-only. +{ BOOST_STATIC_ASSERT((!is_convertible::value)); } + +template +array_adapter::array_adapter + (const char_type* begin, std::size_t length) + : begin_(const_cast(begin)), // Treated as read-only. + end_(const_cast(begin) + length) // Treated as read-only. +{ BOOST_STATIC_ASSERT((!is_convertible::value)); } + +template +typename array_adapter::pair_type +array_adapter::input_sequence() +{ BOOST_STATIC_ASSERT((is_convertible::value)); + return pair_type(begin_, end_); } + +template +typename array_adapter::pair_type +array_adapter::output_sequence() +{ BOOST_STATIC_ASSERT((is_convertible::value)); + return pair_type(begin_, end_); } + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED diff --git a/boost/iostreams/device/back_inserter.hpp b/boost/iostreams/device/back_inserter.hpp new file mode 100644 index 0000000..669c889 --- /dev/null +++ b/boost/iostreams/device/back_inserter.hpp @@ -0,0 +1,41 @@ +// (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 BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // streamsize. +#include + +namespace boost { namespace iostreams { + +template +class back_insert_device { +public: + typedef typename Container::value_type char_type; + typedef sink_tag category; + back_insert_device(Container& cnt) : container(&cnt) { } + std::streamsize write(const char_type* s, std::streamsize n) + { + container->insert(container->end(), s, s + n); + return n; + } +protected: + Container* container; +}; + +template +back_insert_device back_inserter(Container& cnt) +{ return back_insert_device(cnt); } + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED diff --git a/boost/iostreams/device/file.hpp b/boost/iostreams/device/file.hpp new file mode 100644 index 0000000..3eb0301 --- /dev/null +++ b/boost/iostreams/device/file.hpp @@ -0,0 +1,191 @@ +// (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 BOOST_IOSTREAMS_FILE_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#ifndef BOOST_IOSTREAMS_NO_LOCALE +# include +#endif +#include // pathnames, char_traits. +#include +#include // openmode, seekdir, int types. +#include +#include // seek. +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +template +class basic_file { +public: + typedef Ch char_type; + struct category + : public seekable_device_tag, + public closable_tag, + public localizable_tag, + public flushable_tag + { }; + basic_file( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + BOOST_IOS::openmode base_mode = + BOOST_IOS::in | BOOST_IOS::out ); + std::streamsize read(char_type* s, std::streamsize n); + bool putback(char_type c); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = + BOOST_IOS::in | BOOST_IOS::out ); + void open( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + BOOST_IOS::openmode base_mode = + BOOST_IOS::in | BOOST_IOS::out ); + bool is_open() const; + void close(); + bool flush(); +#ifndef BOOST_IOSTREAMS_NO_LOCALE + void imbue(const std::locale& loc) { pimpl_->file_.pubimbue(loc); } +#endif +private: + struct impl { + impl(const std::string& path, BOOST_IOS::openmode mode) + { file_.open(path.c_str(), mode); } + ~impl() { if (file_.is_open()) file_.close(); } + BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) file_; + }; + shared_ptr pimpl_; +}; + +typedef basic_file file; +typedef basic_file wfile; + +template +struct basic_file_source : private basic_file { + typedef Ch char_type; + struct category + : input_seekable, + device_tag, + closable_tag + { }; + using basic_file::read; + using basic_file::putback; + using basic_file::seek; + using basic_file::is_open; + using basic_file::close; + basic_file_source( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in ) + : basic_file(path, mode & ~BOOST_IOS::out, BOOST_IOS::in) + { } + void open( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::in ) + { + basic_file::open(path, mode & ~BOOST_IOS::out, BOOST_IOS::in); + } +}; + +typedef basic_file_source file_source; +typedef basic_file_source wfile_source; + +template +struct basic_file_sink : private basic_file { + typedef Ch char_type; + struct category + : output_seekable, + device_tag, + closable_tag, + flushable_tag + { }; + using basic_file::write; + using basic_file::seek; + using basic_file::is_open; + using basic_file::close; + using basic_file::flush; + basic_file_sink( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ) + : basic_file(path, mode & ~BOOST_IOS::in, BOOST_IOS::out) + { } + void open( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ) + { + basic_file::open(path, mode & ~BOOST_IOS::in, BOOST_IOS::out); + } +}; + +typedef basic_file_sink file_sink; +typedef basic_file_sink wfile_sink; + +//------------------Implementation of basic_file------------------------------// + +template +basic_file::basic_file + ( const std::string& path, BOOST_IOS::openmode mode, + BOOST_IOS::openmode base_mode ) +{ + open(path, mode, base_mode); +} + +template +inline std::streamsize basic_file::read + (char_type* s, std::streamsize n) +{ + std::streamsize result = pimpl_->file_.sgetn(s, n); + return result != 0 ? result : -1; +} + +template +inline bool basic_file::putback(char_type c) +{ + return !!pimpl_->file_.sputbackc(c); +} + +template +inline std::streamsize basic_file::write + (const char_type* s, std::streamsize n) +{ return pimpl_->file_.sputn(s, n); } + +template +std::streampos basic_file::seek + ( stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode ) +{ return iostreams::seek(pimpl_->file_, off, way); } + +template +void basic_file::open + ( const std::string& path, BOOST_IOS::openmode mode, + BOOST_IOS::openmode base_mode ) +{ + pimpl_.reset(new impl(path, mode | base_mode)); +} + +template +bool basic_file::is_open() const { return pimpl_->file_.is_open(); } + +template +void basic_file::close() { pimpl_->file_.close(); } + +template +bool basic_file::flush() +{ return pimpl_->file_.BOOST_IOSTREAMS_PUBSYNC() == 0; } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // MSVC + +#endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED diff --git a/boost/iostreams/device/file_descriptor.hpp b/boost/iostreams/device/file_descriptor.hpp new file mode 100644 index 0000000..5d6af12 --- /dev/null +++ b/boost/iostreams/device/file_descriptor.hpp @@ -0,0 +1,325 @@ +// (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. + +// Inspired by fdstream.hpp, (C) Copyright Nicolai M. Josuttis 2001, +// available at http://www.josuttis.com/cppcode/fdstream.html. + +#ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // intmax_t. +#include // tags. +#include +#include +#include +#include +#include // openmode, seekdir, int types. +#include +#include +#include + +// Must come last. +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4251) // Missing DLL interface for shared_ptr +#endif +#include + +namespace boost { namespace iostreams { + +// Forward declarations +class file_descriptor_source; +class file_descriptor_sink; +namespace detail { struct file_descriptor_impl; } + +enum file_descriptor_flags +{ + never_close_handle = 0, + close_handle = 3 +}; + +class BOOST_IOSTREAMS_DECL file_descriptor { +public: + friend class file_descriptor_source; + friend class file_descriptor_sink; + typedef detail::file_handle handle_type; + typedef char char_type; + struct category + : seekable_device_tag, + closable_tag + { }; + + // Default constructor + file_descriptor(); + + // Constructors taking file desciptors + file_descriptor(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + file_descriptor(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // Constructors taking file desciptors + explicit file_descriptor(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor(int fd, bool close_on_exit = false); +#endif +#endif + + // Constructor taking a std:: string + explicit file_descriptor( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ); + + // Constructor taking a C-style string + explicit file_descriptor( const char* path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ); + + // Constructor taking a Boost.Filesystem path + template + explicit file_descriptor( const Path& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ) + { + init(); + open(detail::path(path), mode); + } + + // Copy constructor + file_descriptor(const file_descriptor& other); + + // open overloads taking file descriptors + void open(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // open overloads taking file descriptors + void open(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, bool close_on_exit = false); +#endif +#endif + + // open overload taking a std::string + void open( const std::string& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ); + + // open overload taking C-style string + void open( const char* path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ); + + // open overload taking a Boost.Filesystem path + template + void open( const Path& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out ) + { open(detail::path(path), mode); } + + bool is_open() const; + void close(); + std::streamsize read(char_type* s, std::streamsize n); + std::streamsize write(const char_type* s, std::streamsize n); + std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); + handle_type handle() const; +private: + void init(); + + // open overload taking a detail::path + void open( const detail::path& path, + BOOST_IOS::openmode, + BOOST_IOS::openmode = BOOST_IOS::openmode(0) ); + + typedef detail::file_descriptor_impl impl_type; + shared_ptr pimpl_; +}; + +class BOOST_IOSTREAMS_DECL file_descriptor_source : private file_descriptor { +public: +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* handle_type; // A.k.a HANDLE +#else + typedef int handle_type; +#endif + typedef char char_type; + struct category + : input_seekable, + device_tag, + closable_tag + { }; + using file_descriptor::is_open; + using file_descriptor::close; + using file_descriptor::read; + using file_descriptor::seek; + using file_descriptor::handle; + + // Default constructor + file_descriptor_source() { } + + // Constructors taking file desciptors + explicit file_descriptor_source(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor_source(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // Constructors taking file desciptors + explicit file_descriptor_source(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor_source(int fd, bool close_on_exit = false); +#endif +#endif + + // Constructor taking a std:: string + explicit file_descriptor_source( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::in ); + + // Constructor taking a C-style string + explicit file_descriptor_source( const char* path, + BOOST_IOS::openmode mode = BOOST_IOS::in ); + + // Constructor taking a Boost.Filesystem path + template + explicit file_descriptor_source( const Path& path, + BOOST_IOS::openmode mode = BOOST_IOS::in ) + { open(detail::path(path), mode); } + + // Copy constructor + file_descriptor_source(const file_descriptor_source& other); + + // Constructors taking file desciptors + void open(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // open overloads taking file descriptors + void open(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, bool close_on_exit = false); +#endif +#endif + + // open overload taking a std::string + void open(const std::string& path, BOOST_IOS::openmode mode = BOOST_IOS::in); + + // open overload taking C-style string + void open(const char* path, BOOST_IOS::openmode mode = BOOST_IOS::in); + + // open overload taking a Boost.Filesystem path + template + void open(const Path& path, BOOST_IOS::openmode mode = BOOST_IOS::in); +private: + + // open overload taking a detail::path + void open(const detail::path& path, BOOST_IOS::openmode); +}; + +class BOOST_IOSTREAMS_DECL file_descriptor_sink : private file_descriptor { +public: +#ifdef BOOST_IOSTREAMS_WINDOWS + typedef void* handle_type; // A.k.a HANDLE +#else + typedef int handle_type; +#endif + typedef char char_type; + struct category + : output_seekable, + device_tag, + closable_tag + { }; + using file_descriptor::is_open; + using file_descriptor::close; + using file_descriptor::write; + using file_descriptor::seek; + using file_descriptor::handle; + + // Default constructor + file_descriptor_sink() { } + + // Constructors taking file desciptors + file_descriptor_sink(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + file_descriptor_sink(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // Constructors taking file desciptors + explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + explicit file_descriptor_sink(int fd, bool close_on_exit = false); +#endif +#endif + + // Constructor taking a std:: string + explicit file_descriptor_sink( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ); + + // Constructor taking a C-style string + explicit file_descriptor_sink( const char* path, + BOOST_IOS::openmode mode = BOOST_IOS::out ); + + // Constructor taking a Boost.Filesystem path + template + explicit file_descriptor_sink( const Path& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ) + { open(detail::path(path), mode); } + + // Copy constructor + file_descriptor_sink(const file_descriptor_sink& other); + + // open overloads taking file descriptors + void open(handle_type fd, file_descriptor_flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, file_descriptor_flags); +#endif + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) + // open overloads taking file descriptors + void open(handle_type fd, bool close_on_exit = false); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, bool close_on_exit = false); +#endif +#endif + + // open overload taking a std::string + void open( const std::string& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ); + + // open overload taking C-style string + void open( const char* path, + BOOST_IOS::openmode mode = BOOST_IOS::out ); + + // open overload taking a Boost.Filesystem path + template + void open( const Path& path, + BOOST_IOS::openmode mode = BOOST_IOS::out ) + { open(detail::path(path), mode); } +private: + + // open overload taking a detail::path + void open(const detail::path& path, BOOST_IOS::openmode); +}; + +} } // End namespaces iostreams, boost. + +#include // pops abi_suffix.hpp pragmas +#if defined(BOOST_MSVC) +# pragma warning(pop) // pops #pragma warning(disable:4251) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_FILE_DESCRIPTOR_HPP_INCLUDED diff --git a/boost/iostreams/device/mapped_file.hpp b/boost/iostreams/device/mapped_file.hpp new file mode 100644 index 0000000..1332bea --- /dev/null +++ b/boost/iostreams/device/mapped_file.hpp @@ -0,0 +1,609 @@ +// (C) Copyright Jorge Lodos 2008. +// (C) Copyright Jonathan Turkanis 2003. +// (C) Copyright Craig Henderson 2002. 'boost/memmap.hpp' from sandbox +// 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.) + +#ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED +#define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // make sure size_t is in std. +#include // size_t. +#include // pathnames. +#include // pair. +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include +#include // openmode, failure +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4251) // Missing DLL interface for shared_ptr +#endif +#include + +namespace boost { namespace iostreams { + +//------------------Definition of mapped_file_base and mapped_file_params-----// + +// Forward declarations +class mapped_file_source; +class mapped_file_sink; +class mapped_file; +namespace detail { class mapped_file_impl; } + +class mapped_file_base { +public: + enum mapmode { + readonly = 1, + readwrite = 2, + priv = 4 + }; +}; + +// Bitmask operations for mapped_file_base::mapmode +mapped_file_base::mapmode +operator|(mapped_file_base::mapmode a, mapped_file_base::mapmode b); + +mapped_file_base::mapmode +operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b); + +mapped_file_base::mapmode +operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b); + +mapped_file_base::mapmode +operator~(mapped_file_base::mapmode a); + +mapped_file_base::mapmode +operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); + +mapped_file_base::mapmode +operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); + +mapped_file_base::mapmode +operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); + +//------------------Definition of mapped_file_params--------------------------// + +namespace detail { + +struct mapped_file_params_base { + mapped_file_params_base() + : flags(static_cast(0)), + mode(), offset(0), length(static_cast(-1)), + new_file_size(0), hint(0) + { } +private: + friend class mapped_file_impl; + void normalize(); +public: + mapped_file_base::mapmode flags; + BOOST_IOS::openmode mode; // Deprecated + stream_offset offset; + std::size_t length; + stream_offset new_file_size; + const char* hint; +}; + +} // End namespace detail. + +// This template allows Boost.Filesystem paths to be specified when creating or +// reopening a memory mapped file, without creating a dependence on +// Boost.Filesystem. Possible values of Path include std::string, +// boost::filesystem::path, boost::filesystem::wpath, +// and boost::iostreams::detail::path (used to store either a std::string or a +// std::wstring). +template +struct basic_mapped_file_params + : detail::mapped_file_params_base +{ + typedef detail::mapped_file_params_base base_type; + + // For wide paths, instantiate basic_mapped_file_params + // with boost::filesystem::wpath +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS + BOOST_STATIC_ASSERT((!is_same::value)); +#endif + + // Default constructor + basic_mapped_file_params() { } + + // Construction from a Path + explicit basic_mapped_file_params(const Path& p) : path(p) { } + + // Construction from a path of a different type + template + explicit basic_mapped_file_params(const PathT& p) : path(p) { } + + // Copy constructor + basic_mapped_file_params(const basic_mapped_file_params& other) + : base_type(other), path(other.path) + { } + + // Templated copy constructor + template + basic_mapped_file_params(const basic_mapped_file_params& other) + : base_type(other), path(other.path) + { } + + typedef Path path_type; + Path path; +}; + +typedef basic_mapped_file_params mapped_file_params; + +//------------------Definition of mapped_file_source--------------------------// + +class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base { +private: + struct safe_bool_helper { int x; }; + typedef int safe_bool_helper::* safe_bool; + typedef detail::mapped_file_impl impl_type; + typedef basic_mapped_file_params param_type; + friend class mapped_file; + friend class detail::mapped_file_impl; + friend struct boost::iostreams::operations; +public: + typedef char char_type; + struct category + : public source_tag, + public direct_tag, + public closable_tag + { }; + typedef std::size_t size_type; + typedef const char* iterator; + BOOST_STATIC_CONSTANT(size_type, max_length = static_cast(-1)); + + // Default constructor + mapped_file_source(); + + // Constructor taking a parameters object + template + explicit mapped_file_source(const basic_mapped_file_params& p); + + // Constructor taking a list of parameters + template + explicit mapped_file_source( const Path& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); + + // Copy Constructor + mapped_file_source(const mapped_file_source& other); + + //--------------Stream interface------------------------------------------// + + template + void open(const basic_mapped_file_params& p); + + template + void open( const Path& path, + size_type length = max_length, + boost::intmax_t offset = 0 ); + + bool is_open() const; + void close(); + operator safe_bool() const; + bool operator!() const; + mapmode flags() const; + + //--------------Container interface---------------------------------------// + + size_type size() const; + const char* data() const; + iterator begin() const; + iterator end() const; + + //--------------Query admissible offsets----------------------------------// + + // Returns the allocation granularity for virtual memory. Values passed + // as offsets must be multiples of this value. + static int alignment(); + +private: + void init(); + void open_impl(const param_type& p); + + boost::shared_ptr pimpl_; +}; + +//------------------Definition of mapped_file---------------------------------// + +class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base { +private: + typedef mapped_file_source delegate_type; + typedef delegate_type::safe_bool safe_bool; + typedef basic_mapped_file_params param_type; + friend struct boost::iostreams::operations; + friend class mapped_file_sink; +public: + typedef char char_type; + struct category + : public seekable_device_tag, + public direct_tag, + public closable_tag + { }; + typedef mapped_file_source::size_type size_type; + typedef char* iterator; + typedef const char* const_iterator; + BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length); + + // Default constructor + mapped_file() { } + + // Construstor taking a parameters object + template + explicit mapped_file(const basic_mapped_file_params& p); + + // Constructor taking a list of parameters + template + mapped_file( const Path& path, + mapmode flags, + size_type length = max_length, + stream_offset offset = 0 ); + + // Constructor taking a list of parameters, including a + // std::ios_base::openmode (deprecated) + template + explicit mapped_file( const Path& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + size_type length = max_length, + stream_offset offset = 0 ); + + // Copy Constructor + mapped_file(const mapped_file& other); + + //--------------Conversion to mapped_file_source (deprecated)-------------// + + operator mapped_file_source&() { return delegate_; } + operator const mapped_file_source&() const { return delegate_; } + + //--------------Stream interface------------------------------------------// + + // open overload taking a parameters object + template + void open(const basic_mapped_file_params& p); + + // open overload taking a list of parameters + template + void open( const Path& path, + mapmode mode, + size_type length = max_length, + stream_offset offset = 0 ); + + // open overload taking a list of parameters, including a + // std::ios_base::openmode (deprecated) + template + void open( const Path& path, + BOOST_IOS::openmode mode = + BOOST_IOS::in | BOOST_IOS::out, + size_type length = max_length, + stream_offset offset = 0 ); + + bool is_open() const { return delegate_.is_open(); } + void close() { delegate_.close(); } + operator safe_bool() const { return delegate_; } + bool operator!() const { return !delegate_; } + mapmode flags() const { return delegate_.flags(); } + + //--------------Container interface---------------------------------------// + + size_type size() const { return delegate_.size(); } + char* data() const; + const char* const_data() const { return delegate_.data(); } + iterator begin() const { return data(); } + const_iterator const_begin() const { return const_data(); } + iterator end() const; + const_iterator const_end() const { return const_data() + size(); } + + //--------------Query admissible offsets----------------------------------// + + // Returns the allocation granularity for virtual memory. Values passed + // as offsets must be multiples of this value. + static int alignment() { return mapped_file_source::alignment(); } + + //--------------File access----------------------------------------------// + + void resize(stream_offset new_size); +private: + delegate_type delegate_; +}; + +//------------------Definition of mapped_file_sink----------------------------// + +class BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file { +public: + friend struct boost::iostreams::operations; + using mapped_file::mapmode; + using mapped_file::readonly; + using mapped_file::readwrite; + using mapped_file::priv; + using mapped_file::char_type; + struct category + : public sink_tag, + public direct_tag, + public closable_tag + { }; + using mapped_file::size_type; + using mapped_file::iterator; + using mapped_file::max_length; + using mapped_file::is_open; + using mapped_file::close; + using mapped_file::operator safe_bool; + using mapped_file::operator !; + using mapped_file::flags; + using mapped_file::size; + using mapped_file::data; + using mapped_file::begin; + using mapped_file::end; + using mapped_file::alignment; + using mapped_file::resize; + + // Default constructor + mapped_file_sink() { } + + // Constructor taking a parameters object + template + explicit mapped_file_sink(const basic_mapped_file_params& p); + + // Constructor taking a list of parameters + template + explicit mapped_file_sink( const Path& path, + size_type length = max_length, + boost::intmax_t offset = 0, + mapmode flags = readwrite ); + + // Copy Constructor + mapped_file_sink(const mapped_file_sink& other); + + // open overload taking a parameters object + template + void open(const basic_mapped_file_params& p); + + // open overload taking a list of parameters + template + void open( const Path& path, + size_type length = max_length, + boost::intmax_t offset = 0, + mapmode flags = readwrite ); +}; + +//------------------Implementation of mapped_file_source----------------------// + +template +mapped_file_source::mapped_file_source(const basic_mapped_file_params& p) +{ init(); open(p); } + +template +mapped_file_source::mapped_file_source( + const Path& path, size_type length, boost::intmax_t offset) +{ init(); open(path, length, offset); } + +template +void mapped_file_source::open(const basic_mapped_file_params& p) +{ + param_type params(p); + if (params.flags) { + if (params.flags != mapped_file::readonly) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags")); + } else { + if (params.mode & BOOST_IOS::out) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); + params.mode |= BOOST_IOS::in; + } + open_impl(params); +} + +template +void mapped_file_source::open( + const Path& path, size_type length, boost::intmax_t offset) +{ + param_type p(path); + p.length = length; + p.offset = offset; + open(p); +} + +//------------------Implementation of mapped_file-----------------------------// + +template +mapped_file::mapped_file(const basic_mapped_file_params& p) +{ open(p); } + +template +mapped_file::mapped_file( + const Path& path, mapmode flags, + size_type length, stream_offset offset ) +{ open(path, flags, length, offset); } + +template +mapped_file::mapped_file( + const Path& path, BOOST_IOS::openmode mode, + size_type length, stream_offset offset ) +{ open(path, mode, length, offset); } + +template +void mapped_file::open(const basic_mapped_file_params& p) +{ delegate_.open_impl(p); } + +template +void mapped_file::open( + const Path& path, mapmode flags, + size_type length, stream_offset offset ) +{ + param_type p(path); + p.flags = flags; + p.length = length; + p.offset = offset; + open(p); +} + +template +void mapped_file::open( + const Path& path, BOOST_IOS::openmode mode, + size_type length, stream_offset offset ) +{ + param_type p(path); + p.mode = mode; + p.length = length; + p.offset = offset; + open(p); +} + +inline char* mapped_file::data() const +{ return (flags() != readonly) ? const_cast(delegate_.data()) : 0; } + +inline mapped_file::iterator mapped_file::end() const +{ return (flags() != readonly) ? data() + size() : 0; } + +//------------------Implementation of mapped_file_sink------------------------// + +template +mapped_file_sink::mapped_file_sink(const basic_mapped_file_params& p) +{ open(p); } + +template +mapped_file_sink::mapped_file_sink( + const Path& path, size_type length, + boost::intmax_t offset, mapmode flags ) +{ open(path, length, offset, flags); } + +template +void mapped_file_sink::open(const basic_mapped_file_params& p) +{ + param_type params(p); + if (params.flags) { + if (params.flags & mapped_file::readonly) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags")); + } else { + if (params.mode & BOOST_IOS::in) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); + params.mode |= BOOST_IOS::out; + } + mapped_file::open(params); +} + +template +void mapped_file_sink::open( + const Path& path, size_type length, + boost::intmax_t offset, mapmode flags ) +{ + param_type p(path); + p.flags = flags; + p.length = length; + p.offset = offset; + open(p); +} + +//------------------Specialization of direct_impl-----------------------------// + +template<> +struct operations + : boost::iostreams::detail::close_impl +{ + static std::pair + input_sequence(mapped_file_source& src) + { + return std::make_pair( const_cast(src.begin()), + const_cast(src.end()) ); + } +}; + +template<> +struct operations + : boost::iostreams::detail::close_impl +{ + static std::pair + input_sequence(mapped_file& file) + { + return std::make_pair(file.begin(), file.end()); + } + static std::pair + output_sequence(mapped_file& file) + { + return std::make_pair(file.begin(), file.end()); + } +}; + +template<> +struct operations + : boost::iostreams::detail::close_impl +{ + static std::pair + output_sequence(mapped_file_sink& sink) + { + return std::make_pair(sink.begin(), sink.end()); + } +}; + +//------------------Definition of mapmode operators---------------------------// + +inline mapped_file::mapmode +operator|(mapped_file::mapmode a, mapped_file::mapmode b) +{ + return static_cast + (static_cast(a) | static_cast(b)); +} + +inline mapped_file::mapmode +operator&(mapped_file::mapmode a, mapped_file::mapmode b) +{ + return static_cast + (static_cast(a) & static_cast(b)); +} + +inline mapped_file::mapmode +operator^(mapped_file::mapmode a, mapped_file::mapmode b) +{ + return static_cast + (static_cast(a) ^ static_cast(b)); +} + +inline mapped_file::mapmode +operator~(mapped_file::mapmode a) +{ + return static_cast(~static_cast(a)); +} + +inline mapped_file::mapmode +operator|=(mapped_file::mapmode& a, mapped_file::mapmode b) +{ + return a = a | b; +} + +inline mapped_file::mapmode +operator&=(mapped_file::mapmode& a, mapped_file::mapmode b) +{ + return a = a & b; +} + +inline mapped_file::mapmode +operator^=(mapped_file::mapmode& a, mapped_file::mapmode b) +{ + return a = a ^ b; +} + +} } // End namespaces iostreams, boost. + +#include // pops abi_suffix.hpp pragmas +#if defined(BOOST_MSVC) +# pragma warning(pop) // pops #pragma warning(disable:4251) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED diff --git a/boost/iostreams/device/null.hpp b/boost/iostreams/device/null.hpp new file mode 100644 index 0000000..a3943d7 --- /dev/null +++ b/boost/iostreams/device/null.hpp @@ -0,0 +1,66 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-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. + +// Inspired by Daryle Walker's nullbuf from his More I/O submission. + +#ifndef BOOST_IOSTREAMS_NULL_HPP_INCLUDED +#define BOOST_IOSTREAMS_NULL_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // openmode, streamsize. +#include + +namespace boost { namespace iostreams { + +template +class basic_null_device { +public: + typedef Ch char_type; + struct category + : public Mode, + public device_tag, + public closable_tag + { }; + std::streamsize read(Ch*, std::streamsize) { return -1; } + std::streamsize write(const Ch*, std::streamsize n) { return n; } + std::streampos seek( stream_offset, BOOST_IOS::seekdir, + BOOST_IOS::openmode = + BOOST_IOS::in | BOOST_IOS::out ) + { return -1; } + void close() { } + void close(BOOST_IOS::openmode) { } +}; + +template +struct basic_null_source : private basic_null_device { + typedef Ch char_type; + typedef source_tag category; + using basic_null_device::read; + using basic_null_device::close; +}; + +typedef basic_null_source null_source; +typedef basic_null_source wnull_source; + +template +struct basic_null_sink : private basic_null_device { + typedef Ch char_type; + typedef sink_tag category; + using basic_null_device::write; + using basic_null_device::close; +}; + +typedef basic_null_sink null_sink; +typedef basic_null_sink wnull_sink; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_NULL_HPP_INCLUDED diff --git a/boost/iostreams/filter/aggregate.hpp b/boost/iostreams/filter/aggregate.hpp new file mode 100644 index 0000000..a645a75 --- /dev/null +++ b/boost/iostreams/filter/aggregate.hpp @@ -0,0 +1,168 @@ +// (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 BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // copy, min. +#include +#include // back_inserter +#include +#include // default_device_buffer_size +#include +#include +#include // openmode, streamsize. +#include +#include // check_eof +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +// +// Template name: aggregate_filter. +// Template parameters: +// Ch - The character type. +// Alloc - The allocator type. +// Description: Utility for defining DualUseFilters which filter an +// entire stream at once. To use, override the protected virtual +// member do_filter. +// Note: This filter should not be copied while it is in use. +// +template > +class aggregate_filter { +public: + typedef Ch char_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + aggregate_filter() : ptr_(0), state_(0) { } + virtual ~aggregate_filter() { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + BOOST_ASSERT(!(state_ & f_write)); + state_ |= f_read; + if (!(state_ & f_eof)) + do_read(src); + std::streamsize amt = + (std::min)(n, static_cast(data_.size() - ptr_)); + if (amt) { + BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt); + ptr_ += amt; + } + return detail::check_eof(amt); + } + + template + std::streamsize write(Sink&, const char_type* s, std::streamsize n) + { + BOOST_ASSERT(!(state_ & f_read)); + state_ |= f_write; + data_.insert(data_.end(), s, s + n); + return n; + } + + template + void close(Sink& sink, BOOST_IOS::openmode which) + { + if ((state_ & f_read) != 0 && which == BOOST_IOS::in) + close_impl(); + if ((state_ & f_write) != 0 && which == BOOST_IOS::out) { + try { + vector_type filtered; + do_filter(data_, filtered); + do_write( + sink, &filtered[0], + static_cast(filtered.size()) + ); + } catch (...) { + close_impl(); + throw; + } + close_impl(); + } + } + +protected: + typedef std::vector vector_type; + typedef typename vector_type::size_type size_type; +private: + virtual void do_filter(const vector_type& src, vector_type& dest) = 0; + virtual void do_close() { } + + template + void do_read(Source& src) + { + using std::streamsize; + vector_type data; + while (true) { + const std::streamsize size = default_device_buffer_size; + Ch buf[size]; + std::streamsize amt; + if ((amt = boost::iostreams::read(src, buf, size)) == -1) + break; + data.insert(data.end(), buf, buf + amt); + } + do_filter(data, data_); + state_ |= f_eof; + } + + template + void do_write(Sink& sink, const char_type* s, std::streamsize n) + { + typedef typename iostreams::category_of::type category; + typedef is_convertible can_write; + do_write(sink, s, n, can_write()); + } + + template + void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_) + { iostreams::write(sink, s, n); } + + template + void do_write(Sink&, const char_type*, std::streamsize, mpl::false_) { } + + void close_impl() + { + data_.clear(); + ptr_ = 0; + state_ = 0; + do_close(); + } + + enum flag_type { + f_read = 1, + f_write = f_read << 1, + f_eof = f_write << 1 + }; + + // Note: typically will not be copied while vector contains data. + vector_type data_; + size_type ptr_; + int state_; +}; +BOOST_IOSTREAMS_PIPABLE(aggregate_filter, 1) + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/bzip2.hpp b/boost/iostreams/filter/bzip2.hpp new file mode 100644 index 0000000..435a9d3 --- /dev/null +++ b/boost/iostreams/filter/bzip2.hpp @@ -0,0 +1,431 @@ +// (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. + +// Note: custom allocators are not supported on VC6, since that compiler +// had trouble finding the function zlib_base::do_init. + +#ifndef BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED +#define BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // allocator. +#include // bad_alloc. +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include +#include // buffer size. +#include +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4231 4660) +#endif +#include + +// Temporary fix. +#undef small + +namespace boost { namespace iostreams { + +namespace bzip2 { + + // Typedefs. + +typedef void* (*alloc_func)(void*, int, int); +typedef void (*free_func)(void*, void*); + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int ok; +BOOST_IOSTREAMS_DECL extern const int run_ok; +BOOST_IOSTREAMS_DECL extern const int flush_ok; +BOOST_IOSTREAMS_DECL extern const int finish_ok; +BOOST_IOSTREAMS_DECL extern const int stream_end; +BOOST_IOSTREAMS_DECL extern const int sequence_error; +BOOST_IOSTREAMS_DECL extern const int param_error; +BOOST_IOSTREAMS_DECL extern const int mem_error; +BOOST_IOSTREAMS_DECL extern const int data_error; +BOOST_IOSTREAMS_DECL extern const int data_error_magic; +BOOST_IOSTREAMS_DECL extern const int io_error; +BOOST_IOSTREAMS_DECL extern const int unexpected_eof; +BOOST_IOSTREAMS_DECL extern const int outbuff_full; +BOOST_IOSTREAMS_DECL extern const int config_error; + + // Action codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int run; + + // Default values + +const int default_block_size = 9; +const int default_work_factor = 30; +const bool default_small = false; + +} // End namespace bzip2. + +// +// Class name: bzip2_params. +// Description: Encapsulates the parameters passed to deflateInit2 +// to customize compression. +// +struct bzip2_params { + + // Non-explicit constructor for compression. + bzip2_params( int block_size_ = bzip2::default_block_size, + int work_factor_ = bzip2::default_work_factor ) + : block_size(block_size_), work_factor(work_factor_) + { } + + // Constructor for decompression. + bzip2_params(bool small) + : small(small), work_factor(0) + { } + + union { + int block_size; // For compression. + bool small; // For decompression. + }; + int work_factor; +}; + +// +// Class name: bzip2_error. +// Description: Subclass of std::ios_base::failure thrown to indicate +// bzip2 errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL bzip2_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit bzip2_error(int error); + int error() const { return error_; } + static void check BOOST_PREVENT_MACRO_SUBSTITUTION(int error); +private: + int error_; +}; + +namespace detail { + +template +struct bzip2_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Alloc::template rebind::other type; +#else + typedef typename std::allocator_traits::template rebind_alloc type; +#endif +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME bzip2_allocator_traits::type > +struct bzip2_allocator : private Base { +private: +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + typedef typename Base::size_type size_type; +#else + typedef typename std::allocator_traits::size_type size_type; +#endif +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename bzip2_allocator_traits::type allocator_type; + static void* allocate(void* self, int items, int size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL bzip2_base { +public: + typedef char char_type; +protected: + bzip2_base(const bzip2_params& params); + ~bzip2_base(); + bzip2_params& params() { return params_; } + bool& ready() { return ready_; } + template + void init( bool compress, + bzip2_allocator& alloc ) + { + bool custom = bzip2_allocator::custom; + do_init( compress, + custom ? bzip2_allocator::allocate : 0, + custom ? bzip2_allocator::deallocate : 0, + custom ? &alloc : 0 ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after(const char*& src_begin, char*& dest_begin); + int check_end(const char* src_begin, const char* dest_begin); + int compress(int action); + int decompress(); + int end(bool compress, std::nothrow_t); + void end(bool compress); +private: + void do_init( bool compress, + bzip2::alloc_func, + bzip2::free_func, + void* derived ); + bzip2_params params_; + void* stream_; // Actual type: bz_stream*. + bool ready_; +}; + +// +// Template name: bzip2_compressor_impl +// Description: Model of SymmetricFilter implementing compression by +// delegating to the libbzip2 function BZ_bzCompress. +// +template > +class bzip2_compressor_impl + : public bzip2_base, + #if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + public + #endif + bzip2_allocator +{ +public: + bzip2_compressor_impl(const bzip2_params&); + ~bzip2_compressor_impl(); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +private: + void init(); + bool eof_; // Guard to make sure filter() isn't called after it returns false. +}; + +// +// Template name: bzip2_compressor +// Description: Model of SymmetricFilter implementing decompression by +// delegating to the libbzip2 function BZ_bzDecompress. +// +template > +class bzip2_decompressor_impl + : public bzip2_base, + #if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + public + #endif + bzip2_allocator +{ +public: + bzip2_decompressor_impl(bool small = bzip2::default_small); + ~bzip2_decompressor_impl(); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); +private: + void init(); + bool eof_; // Guard to make sure filter() isn't called after it returns false. +}; + +} // End namespace detail. + +// +// Template name: bzip2_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using libbzip2. +// +template > +struct basic_bzip2_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::bzip2_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_bzip2_compressor( const bzip2_params& = bzip2::default_block_size, + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_bzip2_compressor, 1) + +typedef basic_bzip2_compressor<> bzip2_compressor; + +// +// Template name: bzip2_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using libbzip2. +// +template > +struct basic_bzip2_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::bzip2_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_bzip2_decompressor( bool small = bzip2::default_small, + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_bzip2_decompressor, 1) + +typedef basic_bzip2_decompressor<> bzip2_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of bzip2_allocator-------------------------// + +namespace detail { + +template +void* bzip2_allocator::allocate(void* self, int items, int size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void bzip2_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of bzip2_compressor_impl-------------------// + +template +bzip2_compressor_impl::bzip2_compressor_impl(const bzip2_params& p) + : bzip2_base(p), eof_(false) { } + +template +bzip2_compressor_impl::~bzip2_compressor_impl() +{ (void) bzip2_base::end(true, std::nothrow); } + +template +bool bzip2_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + if (!ready()) init(); + if (eof_) return false; + before(src_begin, src_end, dest_begin, dest_end); + int result = compress(flush ? bzip2::finish : bzip2::run); + after(src_begin, dest_begin); + bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + return !(eof_ = result == bzip2::stream_end); +} + +template +void bzip2_compressor_impl::close() +{ + try { + end(true); + } catch (...) { + eof_ = false; + throw; + } + eof_ = false; +} + +template +inline void bzip2_compressor_impl::init() +{ bzip2_base::init(true, static_cast&>(*this)); } + +//------------------Implementation of bzip2_decompressor_impl-----------------// + +template +bzip2_decompressor_impl::bzip2_decompressor_impl(bool small) + : bzip2_base(bzip2_params(small)), eof_(false) { } + +template +bzip2_decompressor_impl::~bzip2_decompressor_impl() +{ (void) bzip2_base::end(false, std::nothrow); } + +template +bool bzip2_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + do { + if (eof_) { + // reset the stream if there are more characters + if(src_begin == src_end) + return false; + else + close(); + } + if (!ready()) + init(); + before(src_begin, src_end, dest_begin, dest_end); + int result = decompress(); + if(result == bzip2::ok && flush) + result = check_end(src_begin, dest_begin); + after(src_begin, dest_begin); + bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + eof_ = result == bzip2::stream_end; + } while (eof_ && src_begin != src_end && dest_begin != dest_end); + return true; +} + +template +void bzip2_decompressor_impl::close() +{ + try { + end(false); + } catch (...) { + eof_ = false; + throw; + } + eof_ = false; +} + +template +inline void bzip2_decompressor_impl::init() +{ bzip2_base::init(false, static_cast&>(*this)); } +} // End namespace detail. + +//------------------Implementation of bzip2_decompressor----------------------// + +template +basic_bzip2_compressor::basic_bzip2_compressor + (const bzip2_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) + { } + +//------------------Implementation of bzip2_decompressor----------------------// + +template +basic_bzip2_decompressor::basic_bzip2_decompressor + (bool small, std::streamsize buffer_size) + : base_type(buffer_size, small) + { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED diff --git a/boost/iostreams/filter/counter.hpp b/boost/iostreams/filter/counter.hpp new file mode 100644 index 0000000..8cf775e --- /dev/null +++ b/boost/iostreams/filter/counter.hpp @@ -0,0 +1,82 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // count. +#include +#include +#include +#include + +// Must come last. +#include // VC7.1 C4244. + +namespace boost { namespace iostreams { + +// +// Template name: basic_counter. +// Template parameters: +// Ch - The character type. +// Description: Filter which counts lines and characters. +// +template +class basic_counter { +public: + typedef Ch char_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + optimally_buffered_tag + { }; + explicit basic_counter(int first_line = 0, int first_char = 0) + : lines_(first_line), chars_(first_char) + { } + int lines() const { return lines_; } + int characters() const { return chars_; } + std::streamsize optimal_buffer_size() const { return 0; } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + std::streamsize result = iostreams::read(src, s, n); + if (result == -1) + return -1; + lines_ += std::count(s, s + result, char_traits::newline()); + chars_ += result; + return result; + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + std::streamsize result = iostreams::write(snk, s, n); + lines_ += std::count(s, s + result, char_traits::newline()); + chars_ += result; + return result; + } +private: + int lines_; + int chars_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_counter, 1) + + +typedef basic_counter counter; +typedef basic_counter wcounter; + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/grep.hpp b/boost/iostreams/filter/grep.hpp new file mode 100644 index 0000000..b303097 --- /dev/null +++ b/boost/iostreams/filter/grep.hpp @@ -0,0 +1,109 @@ +/* + * 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. + + * File: boost/iostreams/filter/grep.hpp + * Date: Mon May 26 17:48:45 MDT 2008 + * Copyright: 2008 CodeRage, LLC + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the class template basic_grep_filter and its specializations + * grep_filter and wgrep_filter. + */ + +#ifndef BOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_GREP_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#include // allocator. +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace grep { + +const int invert = 1; +const int whole_line = invert << 1; + +} // End namespace grep. + +template< typename Ch, + typename Tr = regex_traits, + typename Alloc = std::allocator > +class basic_grep_filter : public basic_line_filter { +private: + typedef basic_line_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + typedef char_traits traits_type; + typedef typename base_type::string_type string_type; + typedef basic_regex regex_type; + typedef regex_constants::match_flag_type match_flag_type; + basic_grep_filter( const regex_type& re, + match_flag_type match_flags = + regex_constants::match_default, + int options = 0 ); + int count() const { return count_; } + + template + void close(Sink& snk, BOOST_IOS::openmode which) + { + base_type::close(snk, which); + options_ &= ~f_initialized; + } +private: + virtual string_type do_filter(const string_type& line) + { + if ((options_ & f_initialized) == 0) { + options_ |= f_initialized; + count_ = 0; + } + bool matches = (options_ & grep::whole_line) ? + regex_match(line, re_, match_flags_) : + regex_search(line, re_, match_flags_); + if (options_ & grep::invert) + matches = !matches; + if (matches) + ++count_; + return matches ? line + traits_type::newline() : string_type(); + } + + // Private flags bitwise OR'd with constants from namespace grep + enum flags_ { + f_initialized = 65536 + }; + + regex_type re_; + match_flag_type match_flags_; + int options_; + int count_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_grep_filter, 3) + +typedef basic_grep_filter grep_filter; +typedef basic_grep_filter wgrep_filter; + +//------------------Implementation of basic_grep_filter-----------------------// + +template +basic_grep_filter::basic_grep_filter + (const regex_type& re, match_flag_type match_flags, int options) + : base_type(true), re_(re), match_flags_(match_flags), + options_(options), count_(0) + { } + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/gzip.hpp b/boost/iostreams/filter/gzip.hpp new file mode 100644 index 0000000..e236983 --- /dev/null +++ b/boost/iostreams/filter/gzip.hpp @@ -0,0 +1,757 @@ +// (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. + +// Contains the definitions of the class templates gzip_compressor and +// gzip_decompressor for reading and writing files in the gzip file format +// (RFC 1952). Based in part on work of Jonathan de Halleux; see [...] + +#ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED +#define BOOST_IOSTREAMS_GZIP_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // STATIC_CONSTANT, STDC_NAMESPACE, + // DINKUMWARE_STDLIB, __STL_CONFIG_H. +#include // min. +#include +#include // EOF. +#include // size_t. +#include // std::time_t. +#include // allocator. +#include // Put size_t in std. +#include +#include // uint8_t, uint32_t. +#include +#include // buffer size. +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#if defined(BOOST_MSVC) +# pragma warning(push) +# pragma warning(disable:4244) // Possible truncation +# pragma warning(disable:4251) // Missing DLL interface for std::string +# pragma warning(disable:4309) // Truncation of constant value. +#endif + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::time_t; } +#endif + +namespace boost { namespace iostreams { + +//------------------Definitions of constants----------------------------------// + +namespace gzip { + +using namespace boost::iostreams::zlib; + + // Error codes used by gzip_error. + +const int zlib_error = 1; +const int bad_crc = 2; // Recorded crc doesn't match data. +const int bad_length = 3; // Recorded length doesn't match data. +const int bad_header = 4; // Malformed header. +const int bad_footer = 5; // Malformed footer. +const int bad_method = 6; // Unsupported compression method. + +namespace magic { + + // Magic numbers used by gzip header. + +const int id1 = 0x1f; +const int id2 = 0x8b; + +} // End namespace magic. + +namespace method { + + // Codes used for the 'CM' byte of the gzip header. + +const int deflate = 8; + +} // End namespace method. + +namespace flags { + + // Codes used for the 'FLG' byte of the gzip header. + +const int text = 1; +const int header_crc = 2; +const int extra = 4; +const int name = 8; +const int comment = 16; + +} // End namespace flags. + +namespace extra_flags { + + // Codes used for the 'XFL' byte of the gzip header. + +const int best_compression = 2; +const int best_speed = 4; + +} // End namespace extra_flags. + + // Codes used for the 'OS' byte of the gzip header. + +const int os_fat = 0; +const int os_amiga = 1; +const int os_vms = 2; +const int os_unix = 3; +const int os_vm_cms = 4; +const int os_atari = 5; +const int os_hpfs = 6; +const int os_macintosh = 7; +const int os_z_system = 8; +const int os_cp_m = 9; +const int os_tops_20 = 10; +const int os_ntfs = 11; +const int os_qdos = 12; +const int os_acorn = 13; +const int os_unknown = 255; + +} // End namespace gzip. + +//------------------Definition of gzip_params---------------------------------// + +// +// Class name: gzip_params. +// Description: Subclass of zlib_params with an additional field +// representing a file name. +// +struct gzip_params : zlib_params { + + // Non-explicit constructor. + gzip_params( int level = gzip::default_compression, + int method = gzip::deflated, + int window_bits = gzip::default_window_bits, + int mem_level = gzip::default_mem_level, + int strategy = gzip::default_strategy, + std::string file_name_ = "", + std::string comment_ = "", + std::time_t mtime_ = 0 ) + : zlib_params(level, method, window_bits, mem_level, strategy), + file_name(file_name_), comment(comment_), mtime(mtime_) + { } + std::string file_name; + std::string comment; + std::time_t mtime; +}; + +//------------------Definition of gzip_error----------------------------------// + +// +// Class name: gzip_error. +// Description: Subclass of std::ios_base::failure thrown to indicate +// zlib errors other than out-of-memory conditions. +// +class gzip_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit gzip_error(int error) + : BOOST_IOSTREAMS_FAILURE("gzip error"), + error_(error), zlib_error_code_(zlib::okay) { } + explicit gzip_error(const zlib_error& e) + : BOOST_IOSTREAMS_FAILURE("gzip error"), + error_(gzip::zlib_error), zlib_error_code_(e.error()) + { } + int error() const { return error_; } + int zlib_error_code() const { return zlib_error_code_; } +private: + int error_; + int zlib_error_code_; +}; + +//------------------Definition of gzip_compressor-----------------------------// + +// +// Template name: gzip_compressor +// Description: Model of OutputFilter implementing compression in the +// gzip format. +// +template > +class basic_gzip_compressor : basic_zlib_compressor { +private: + typedef basic_zlib_compressor base_type; +public: + typedef char char_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + basic_gzip_compressor( const gzip_params& = gzip::default_compression, + std::streamsize buffer_size = default_device_buffer_size ); + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + std::streamsize result = 0; + + // Read header. + if (!(flags_ & f_header_done)) + result += read_string(s, n, header_); + + // Read body. + if (!(flags_ & f_body_done)) { + + // Read from basic_zlib_filter. + std::streamsize amt = base_type::read(src, s + result, n - result); + if (amt != -1) { + result += amt; + if (amt < n - result) { // Double-check for EOF. + amt = base_type::read(src, s + result, n - result); + if (amt != -1) + result += amt; + } + } + if (amt == -1) + prepare_footer(); + } + + // Read footer. + if ((flags_ & f_body_done) != 0 && result < n) + result += read_string(s + result, n - result, footer_); + + return result != 0 ? result : -1; + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + if (!(flags_ & f_header_done)) { + std::streamsize amt = + static_cast(header_.size() - offset_); + offset_ += boost::iostreams::write_if(snk, header_.data() + offset_, amt); + if (offset_ == header_.size()) + flags_ |= f_header_done; + else + return 0; + } + return base_type::write(snk, s, n); + } + + template + void close(Sink& snk, BOOST_IOS::openmode m) + { + try { + if (m == BOOST_IOS::out && !(flags_ & f_header_done)) + this->write(snk, 0, 0); + + // Close zlib compressor. + base_type::close(snk, m); + + if (m == BOOST_IOS::out) { + if (flags_ & f_header_done) { + + // Write final fields of gzip file format. + write_long(this->crc(), snk); + write_long(this->total_in(), snk); + } + } + } catch(...) { + close_impl(); + throw; + } + close_impl(); + } +private: + static gzip_params normalize_params(gzip_params p); + void prepare_footer(); + std::streamsize read_string(char* s, std::streamsize n, std::string& str); + + template + static void write_long(long n, Sink& next, boost::mpl::true_) + { + boost::iostreams::put(next, static_cast(0xFF & n)); + boost::iostreams::put(next, static_cast(0xFF & (n >> 8))); + boost::iostreams::put(next, static_cast(0xFF & (n >> 16))); + boost::iostreams::put(next, static_cast(0xFF & (n >> 24))); + } + template + static void write_long(long, Sink&, boost::mpl::false_) + { + } + template + static void write_long(long n, Sink& next) + { + typedef typename category_of::type category; + typedef is_convertible can_write; + write_long(n, next, can_write()); + } + + void close_impl() + { + footer_.clear(); + offset_ = 0; + flags_ = 0; + } + + enum state_type { + f_header_done = 1, + f_body_done = f_header_done << 1, + f_footer_done = f_body_done << 1 + }; + std::string header_; + std::string footer_; + std::size_t offset_; + int flags_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_gzip_compressor, 1) + +typedef basic_gzip_compressor<> gzip_compressor; + +//------------------Definition of helper templates for decompression----------// + +namespace detail { + +// Processes gzip headers +class BOOST_IOSTREAMS_DECL gzip_header { +public: + gzip_header() { reset(); } + + // Members for processing header data + void process(char c); + bool done() const { return state_ == s_done; } + void reset(); + + // Members for accessing header data + std::string file_name() const { return file_name_; } + std::string comment() const { return comment_; } + bool text() const { return (flags_ & gzip::flags::text) != 0; } + int os() const { return os_; } + std::time_t mtime() const { return mtime_; } +private: + enum state_type { + s_id1 = 1, + s_id2 = s_id1 + 1, + s_cm = s_id2 + 1, + s_flg = s_cm + 1, + s_mtime = s_flg + 1, + s_xfl = s_mtime + 1, + s_os = s_xfl + 1, + s_xlen = s_os + 1, + s_extra = s_xlen + 1, + s_name = s_extra + 1, + s_comment = s_name + 1, + s_hcrc = s_comment + 1, + s_done = s_hcrc + 1 + }; + std::string file_name_; + std::string comment_; + int os_; + std::time_t mtime_; + int flags_; + int state_; + int offset_; // Offset within fixed-length region. + int xlen_; // Bytes remaining in extra field. +}; + +// Processes gzip footers +class BOOST_IOSTREAMS_DECL gzip_footer { +public: + gzip_footer() { reset(); } + + // Members for processing footer data + void process(char c); + bool done() const { return state_ == s_done; } + void reset(); + + // Members for accessing footer data + zlib::ulong crc() const { return crc_; } + zlib::ulong uncompressed_size() const { return isize_; } +private: + enum state_type { + s_crc = 1, + s_isize = s_crc + 1, + s_done = s_isize + 1 + }; + zlib::ulong crc_; + zlib::ulong isize_; + int state_; + int offset_; +}; + +} // End namespace boost::iostreams::detail. + +//------------------Definition of basic_gzip_decompressor---------------------// + +// +// Template name: basic_gzip_decompressor +// Description: Model of InputFilter implementing compression in the +// gzip format. +// +template > +class basic_gzip_decompressor : basic_zlib_decompressor { +private: + typedef basic_zlib_decompressor base_type; + typedef typename base_type::string_type string_type; +public: + typedef char char_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + basic_gzip_decompressor( int window_bits = gzip::default_window_bits, + std::streamsize buffer_size = default_device_buffer_size ); + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + std::streamsize result = 0; + while(result < n) { + if(state_ == s_start) { + state_ = s_header; + header_.reset(); + footer_.reset(); + } + if (state_ == s_header) { + int c = s[result++]; + header_.process(c); + if (header_.done()) + state_ = s_body; + } else if (state_ == s_body) { + try { + std::streamsize amt = + base_type::write(snk, s + result, n - result); + result += amt; + if (!this->eof()) { + break; + } else { + state_ = s_footer; + } + } catch (const zlib_error& e) { + boost::throw_exception(gzip_error(e)); + } + } else { // state_ == s_footer + if (footer_.done()) { + if (footer_.crc() != this->crc()) + boost::throw_exception(gzip_error(gzip::bad_crc)); + + base_type::close(snk, BOOST_IOS::out); + state_ = s_start; + } else { + int c = s[result++]; + footer_.process(c); + } + } + } + return result; + } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + typedef char_traits traits_type; + std::streamsize result = 0; + peekable_source peek(src, putback_); + while (result < n && state_ != s_done) { + if (state_ == s_start) { + state_ = s_header; + header_.reset(); + footer_.reset(); + } + if (state_ == s_header) { + int c = boost::iostreams::get(peek); + if (traits_type::is_eof(c)) { + boost::throw_exception(gzip_error(gzip::bad_header)); + } else if (traits_type::would_block(c)) { + break; + } + header_.process(c); + if (header_.done()) + state_ = s_body; + } else if (state_ == s_body) { + try { + std::streamsize amt = + base_type::read(peek, s + result, n - result); + if (amt != -1) { + result += amt; + if (amt < n - result) + break; + } else { + peek.putback(this->unconsumed_input()); + state_ = s_footer; + } + } catch (const zlib_error& e) { + boost::throw_exception(gzip_error(e)); + } + } else { // state_ == s_footer + int c = boost::iostreams::get(peek); + if (traits_type::is_eof(c)) { + boost::throw_exception(gzip_error(gzip::bad_footer)); + } else if (traits_type::would_block(c)) { + break; + } + footer_.process(c); + if (footer_.done()) { + if (footer_.crc() != this->crc()) + boost::throw_exception(gzip_error(gzip::bad_crc)); + c = boost::iostreams::get(peek); + if (traits_type::is_eof(c)) { + state_ = s_done; + } else { + peek.putback(c); + base_type::close(peek, BOOST_IOS::in); + state_ = s_start; + header_.reset(); + footer_.reset(); + } + } + } + } + if (peek.has_unconsumed_input()) { + putback_ = peek.unconsumed_input(); + } else { + putback_.clear(); + } + return result != 0 || state_ != s_done ? + result : + -1; + } + + template + void close(Source& src, BOOST_IOS::openmode m) + { + try { + base_type::close(src, m); + } catch (const zlib_error& e) { + state_ = s_start; + boost::throw_exception(gzip_error(e)); + } + if (m == BOOST_IOS::out) { + if (state_ == s_start || state_ == s_header) + boost::throw_exception(gzip_error(gzip::bad_header)); + else if (state_ == s_body) + boost::throw_exception(gzip_error(gzip::bad_footer)); + else if (state_ == s_footer) { + if (!footer_.done()) + boost::throw_exception(gzip_error(gzip::bad_footer)); + else if(footer_.crc() != this->crc()) + boost::throw_exception(gzip_error(gzip::bad_crc)); + } else { + BOOST_ASSERT(!"Bad state"); + } + } + state_ = s_start; + } + + std::string file_name() const { return header_.file_name(); } + std::string comment() const { return header_.comment(); } + bool text() const { return header_.text(); } + int os() const { return header_.os(); } + std::time_t mtime() const { return header_.mtime(); } +private: + static gzip_params make_params(int window_bits); + + // Source adapter allowing an arbitrary character sequence to be put back. + template + struct peekable_source { + typedef char char_type; + struct category : source_tag, peekable_tag { }; + explicit peekable_source(Source& src, const string_type& putback = "") + : src_(src), putback_(putback), offset_(0) + { } + std::streamsize read(char* s, std::streamsize n) + { + std::streamsize result = 0; + + // Copy characters from putback buffer + std::streamsize pbsize = + static_cast(putback_.size()); + if (offset_ < pbsize) { + result = (std::min)(n, pbsize - offset_); + BOOST_IOSTREAMS_CHAR_TRAITS(char)::copy( + s, putback_.data() + offset_, result); + offset_ += result; + if (result == n) + return result; + } + + // Read characters from src_ + std::streamsize amt = + boost::iostreams::read(src_, s + result, n - result); + return amt != -1 ? + result + amt : + result ? result : -1; + } + bool putback(char c) + { + if (offset_) { + putback_[--offset_] = c; + } else { + boost::throw_exception( + boost::iostreams::detail::bad_putback()); + } + return true; + } + void putback(const string_type& s) + { + putback_.replace(0, offset_, s); + offset_ = 0; + } + + // Returns true if some characters have been putback but not re-read. + bool has_unconsumed_input() const + { + return offset_ < static_cast(putback_.size()); + } + + // Returns the sequence of characters that have been put back but not re-read. + string_type unconsumed_input() const + { + return string_type(putback_, offset_, putback_.size() - offset_); + } + Source& src_; + string_type putback_; + std::streamsize offset_; + }; + + enum state_type { + s_start = 1, + s_header = s_start + 1, + s_body = s_header + 1, + s_footer = s_body + 1, + s_done = s_footer + 1 + }; + detail::gzip_header header_; + detail::gzip_footer footer_; + string_type putback_; + int state_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1) + +typedef basic_gzip_decompressor<> gzip_decompressor; + +//------------------Implementation of gzip_compressor-------------------------// + +template +basic_gzip_compressor::basic_gzip_compressor + (const gzip_params& p, std::streamsize buffer_size) + : base_type(normalize_params(p), buffer_size), + offset_(0), flags_(0) +{ + // Calculate gzip header. + bool has_name = !p.file_name.empty(); + bool has_comment = !p.comment.empty(); + + std::string::size_type length = + 10 + + (has_name ? p.file_name.size() + 1 : 0) + + (has_comment ? p.comment.size() + 1 : 0); + // + 2; // Header crc confuses gunzip. + int flags = + //gzip::flags::header_crc + + (has_name ? gzip::flags::name : 0) + + (has_comment ? gzip::flags::comment : 0); + int extra_flags = + ( p.level == zlib::best_compression ? + gzip::extra_flags::best_compression : + 0 ) + + ( p.level == zlib::best_speed ? + gzip::extra_flags::best_speed : + 0 ); + header_.reserve(length); + header_ += gzip::magic::id1; // ID1. + header_ += static_cast(gzip::magic::id2); // ID2. + header_ += gzip::method::deflate; // CM. + header_ += static_cast(flags); // FLG. + header_ += static_cast(0xFF & p.mtime); // MTIME. + header_ += static_cast(0xFF & (p.mtime >> 8)); + header_ += static_cast(0xFF & (p.mtime >> 16)); + header_ += static_cast(0xFF & (p.mtime >> 24)); + header_ += static_cast(extra_flags); // XFL. + header_ += static_cast(gzip::os_unknown); // OS. + if (has_name) { + header_ += p.file_name; + header_ += '\0'; + } + if (has_comment) { + header_ += p.comment; + header_ += '\0'; + } +} + +template +gzip_params basic_gzip_compressor::normalize_params(gzip_params p) +{ + p.noheader = true; + p.calculate_crc = true; + return p; +} + +template +void basic_gzip_compressor::prepare_footer() +{ + boost::iostreams::back_insert_device out(footer_); + write_long(this->crc(), out); + write_long(this->total_in(), out); + flags_ |= f_body_done; + offset_ = 0; +} + +template +std::streamsize basic_gzip_compressor::read_string + (char* s, std::streamsize n, std::string& str) +{ + std::streamsize avail = + static_cast(str.size() - offset_); + std::streamsize amt = (std::min)(avail, n); + std::copy( str.data() + offset_, + str.data() + offset_ + amt, + s ); + offset_ += amt; + if ( !(flags_ & f_header_done) && + offset_ == static_cast(str.size()) ) + { + flags_ |= f_header_done; + } + return amt; +} + +//------------------Implementation of gzip_decompressor-----------------------// + +template +basic_gzip_decompressor::basic_gzip_decompressor + (int window_bits, std::streamsize buffer_size) + : base_type(make_params(window_bits), buffer_size), + state_(s_start) + { } + +template +gzip_params basic_gzip_decompressor::make_params(int window_bits) +{ + gzip_params p; + p.window_bits = window_bits; + p.noheader = true; + p.calculate_crc = true; + return p; +} + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#if defined(BOOST_MSVC) +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_GZIP_HPP_INCLUDED diff --git a/boost/iostreams/filter/line.hpp b/boost/iostreams/filter/line.hpp new file mode 100644 index 0000000..2c66f0e --- /dev/null +++ b/boost/iostreams/filter/line.hpp @@ -0,0 +1,221 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // min. +#include +#include // allocator. +#include +#include // BOOST_STATIC_CONSTANT. +#include +#include +#include // openmode, streamsize. +#include // check_eof +#include +#include + +// Must come last. +#include // VC7.1 C4244. + +namespace boost { namespace iostreams { + +// +// Template name: line_filter. +// Template parameters: +// Ch - The character type. +// Alloc - The allocator type. +// Description: Filter which processes data one line at a time. +// +template< typename Ch, + typename Alloc = std::allocator > +class basic_line_filter { +private: + typedef typename std::basic_string::traits_type string_traits; +public: + typedef Ch char_type; + typedef char_traits traits_type; + typedef std::basic_string< + Ch, + string_traits, + Alloc + > string_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; +protected: + basic_line_filter(bool suppress_newlines = false) + : pos_(string_type::npos), + flags_(suppress_newlines ? f_suppress : 0) + { } +public: + virtual ~basic_line_filter() { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + BOOST_ASSERT(!(flags_ & f_write)); + flags_ |= f_read; + + // Handle unfinished business. + std::streamsize result = 0; + if (!cur_line_.empty() && (result = read_line(s, n)) == n) + return n; + + typename traits_type::int_type status = traits_type::good(); + while (result < n && !traits_type::is_eof(status)) { + + // Call next_line() to retrieve a line of filtered text, and + // read_line() to copy it into buffer s. + if (traits_type::would_block(status = next_line(src))) + return result; + result += read_line(s + result, n - result); + } + + return detail::check_eof(result); + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + using namespace std; + BOOST_ASSERT(!(flags_ & f_read)); + flags_ |= f_write; + + // Handle unfinished business. + if (pos_ != string_type::npos && !write_line(snk)) + return 0; + + const char_type *cur = s, *next; + while (true) { + + // Search for the next full line in [cur, s + n), filter it + // and write it to snk. + typename string_type::size_type rest = n - (cur - s); + if ((next = traits_type::find(cur, rest, traits_type::newline()))) { + cur_line_.append(cur, next - cur); + cur = next + 1; + if (!write_line(snk)) + return static_cast(cur - s); + } else { + cur_line_.append(cur, rest); + return n; + } + } + } + + template + void close(Sink& snk, BOOST_IOS::openmode which) + { + if ((flags_ & f_read) && which == BOOST_IOS::in) + close_impl(); + + if ((flags_ & f_write) && which == BOOST_IOS::out) { + try { + if (!cur_line_.empty()) + write_line(snk); + } catch (...) { + try { + close_impl(); + } catch (...) { } + throw; + } + close_impl(); + } + } +private: + virtual string_type do_filter(const string_type& line) = 0; + + // Copies filtered characters fron the current line into + // the given buffer. + std::streamsize read_line(char_type* s, std::streamsize n) + { + using namespace std; + std::streamsize result = + (std::min) (n, static_cast(cur_line_.size())); + traits_type::copy(s, cur_line_.data(), result); + cur_line_.erase(0, result); + return result; + } + + // Attempts to retrieve a line of text from the given source; returns + // an int_type as a good/eof/would_block status code. + template + typename traits_type::int_type next_line(Source& src) + { + using namespace std; + typename traits_type::int_type c; + while ( traits_type::is_good(c = iostreams::get(src)) && + c != traits_type::newline() ) + { + cur_line_ += traits_type::to_int_type(c); + } + if (!traits_type::would_block(c)) { + if (!cur_line_.empty() || c == traits_type::newline()) + cur_line_ = do_filter(cur_line_); + if (c == traits_type::newline() && (flags_ & f_suppress) == 0) + cur_line_ += c; + } + return c; // status indicator. + } + + // Filters the current line and attemps to write it to the given sink. + // Returns true for success. + template + bool write_line(Sink& snk) + { + string_type line = do_filter(cur_line_); + if ((flags_ & f_suppress) == 0) + line += traits_type::newline(); + std::streamsize amt = static_cast(line.size()); + bool result = iostreams::write_if(snk, line.data(), amt) == amt; + if (result) + clear(); + return result; + } + + void close_impl() + { + clear(); + flags_ &= f_suppress; + } + + void clear() + { + cur_line_.erase(); + pos_ = string_type::npos; + } + + enum flag_type { + f_read = 1, + f_write = f_read << 1, + f_suppress = f_write << 1 + }; + + string_type cur_line_; + typename string_type::size_type pos_; + int flags_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_line_filter, 2) + +typedef basic_line_filter line_filter; +typedef basic_line_filter wline_filter; + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/lzma.hpp b/boost/iostreams/filter/lzma.hpp new file mode 100644 index 0000000..858474c --- /dev/null +++ b/boost/iostreams/filter/lzma.hpp @@ -0,0 +1,376 @@ +// (C) Copyright Milan Svoboda 2008. +// Originally developed under the fusecompress project. +// 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. + +// Note: custom allocators are not supported on VC6, since that compiler +// had trouble finding the function lzma_base::do_init. + +#ifndef BOOST_IOSTREAMS_LZMA_HPP_INCLUDED +#define BOOST_IOSTREAMS_LZMA_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // streamsize. +#include // allocator, bad_alloc. +#include +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include +#include // buffer size. +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4231 4660) // Dependencies not exported. +#endif +#include + +namespace boost { namespace iostreams { + +namespace lzma { + +typedef void* (*alloc_func)(void*, size_t, size_t); +typedef void (*free_func)(void*, void*); + + // Compression levels + +BOOST_IOSTREAMS_DECL extern const uint32_t no_compression; +BOOST_IOSTREAMS_DECL extern const uint32_t best_speed; +BOOST_IOSTREAMS_DECL extern const uint32_t best_compression; +BOOST_IOSTREAMS_DECL extern const uint32_t default_compression; + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int okay; +BOOST_IOSTREAMS_DECL extern const int stream_end; +BOOST_IOSTREAMS_DECL extern const int unsupported_check; +BOOST_IOSTREAMS_DECL extern const int mem_error; +BOOST_IOSTREAMS_DECL extern const int options_error; +BOOST_IOSTREAMS_DECL extern const int data_error; +BOOST_IOSTREAMS_DECL extern const int buf_error; +BOOST_IOSTREAMS_DECL extern const int prog_error; + + // Flush codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int full_flush; +BOOST_IOSTREAMS_DECL extern const int sync_flush; +BOOST_IOSTREAMS_DECL extern const int run; + + // Code for current OS + + // Null pointer constant. + +const int null = 0; + + // Default values + +} // End namespace lzma. + +// +// Class name: lzma_params. +// Description: Encapsulates the parameters passed to lzmadec_init +// to customize compression and decompression. +// +struct lzma_params { + + // Non-explicit constructor. + lzma_params( uint32_t level = lzma::default_compression, uint32_t threads = 1 ) + : level(level) + , threads(threads) + { } + uint32_t level; + uint32_t threads; +}; + +// +// Class name: lzma_error. +// Description: Subclass of std::ios::failure thrown to indicate +// lzma errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL lzma_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit lzma_error(int error); + int error() const { return error_; } + static void check BOOST_PREVENT_MACRO_SUBSTITUTION(int error); +private: + int error_; +}; + +namespace detail { + +template +struct lzma_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Alloc::template rebind::other type; +#else + typedef typename std::allocator_traits::template rebind_alloc type; +#endif +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME lzma_allocator_traits::type > +struct lzma_allocator : private Base { +private: +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + typedef typename Base::size_type size_type; +#else + typedef typename std::allocator_traits::size_type size_type; +#endif +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename lzma_allocator_traits::type allocator_type; + static void* allocate(void* self, size_t items, size_t size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL lzma_base { +public: + typedef char char_type; +protected: + lzma_base(); + ~lzma_base(); + void* stream() { return stream_; } + template + void init( const lzma_params& p, + bool compress, + lzma_allocator& zalloc ) + { + bool custom = lzma_allocator::custom; + do_init( p, compress, + custom ? lzma_allocator::allocate : 0, + custom ? lzma_allocator::deallocate : 0, + &zalloc ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after( const char*& src_begin, char*& dest_begin, + bool compress ); + int deflate(int action); + int inflate(int action); + void reset(bool compress, bool realloc); +private: + void do_init( const lzma_params& p, bool compress, + lzma::alloc_func, + lzma::free_func, + void* derived ); + void init_stream(bool compress); + void* stream_; // Actual type: lzma_stream*. + uint32_t level_; + uint32_t threads_; +}; + +// +// Template name: lzma_compressor_impl +// Description: Model of C-Style Filter implementing compression by +// delegating to the lzma function deflate. +// +template > +class lzma_compressor_impl : public lzma_base, public lzma_allocator { +public: + lzma_compressor_impl(const lzma_params& = lzma_params()); + ~lzma_compressor_impl(); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +}; + +// +// Template name: lzma_compressor_impl +// Description: Model of C-Style Filte implementing decompression by +// delegating to the lzma function inflate. +// +template > +class lzma_decompressor_impl : public lzma_base, public lzma_allocator { +public: + lzma_decompressor_impl(const lzma_params&); + lzma_decompressor_impl(); + ~lzma_decompressor_impl(); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); +}; + +} // End namespace detail. + +// +// Template name: lzma_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using lzma. +// +template > +struct basic_lzma_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::lzma_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_lzma_compressor( const lzma_params& = lzma_params(), + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_lzma_compressor, 1) + +typedef basic_lzma_compressor<> lzma_compressor; + +// +// Template name: lzma_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using lzma. +// +template > +struct basic_lzma_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::lzma_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_lzma_decompressor( std::streamsize buffer_size = default_device_buffer_size ); + basic_lzma_decompressor( const lzma_params& p, + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_lzma_decompressor, 1) + +typedef basic_lzma_decompressor<> lzma_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of lzma_allocator--------------------------// + +namespace detail { + +template +void* lzma_allocator::allocate + (void* self, size_t items, size_t size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void lzma_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of lzma_compressor_impl--------------------// + +template +lzma_compressor_impl::lzma_compressor_impl(const lzma_params& p) +{ init(p, true, static_cast&>(*this)); } + +template +lzma_compressor_impl::~lzma_compressor_impl() +{ reset(true, false); } + +template +bool lzma_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = deflate(flush ? lzma::finish : lzma::run); + after(src_begin, dest_begin, true); + lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + return result != lzma::stream_end; +} + +template +void lzma_compressor_impl::close() { reset(true, true); } + +//------------------Implementation of lzma_decompressor_impl------------------// + +template +lzma_decompressor_impl::lzma_decompressor_impl(const lzma_params& p) +{ init(p, false, static_cast&>(*this)); } + +template +lzma_decompressor_impl::~lzma_decompressor_impl() +{ reset(false, false); } + +template +lzma_decompressor_impl::lzma_decompressor_impl() +{ + lzma_params p; + init(p, false, static_cast&>(*this)); +} + +template +bool lzma_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = inflate(flush ? lzma::finish : lzma::run); + after(src_begin, dest_begin, false); + lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + return result != lzma::stream_end; +} + +template +void lzma_decompressor_impl::close() { reset(false, true); } + +} // End namespace detail. + +//------------------Implementation of lzma_compressor-----------------------// + +template +basic_lzma_compressor::basic_lzma_compressor + (const lzma_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//------------------Implementation of lzma_decompressor-----------------------// + +template +basic_lzma_decompressor::basic_lzma_decompressor + (std::streamsize buffer_size) + : base_type(buffer_size) { } + +template +basic_lzma_decompressor::basic_lzma_decompressor + (const lzma_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_LZMA_HPP_INCLUDED diff --git a/boost/iostreams/filter/newline.hpp b/boost/iostreams/filter/newline.hpp new file mode 100644 index 0000000..57a3639 --- /dev/null +++ b/boost/iostreams/filter/newline.hpp @@ -0,0 +1,441 @@ +// (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. + +// NOTE: I hope to replace the current implementation with a much simpler +// one. + +#ifndef BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include // logic_error. +#include // BOOST_STATIC_CONSTANT. +#include +#include +#include // BOOST_IOSTREAMS_FAILURE +#include // get +#include // put +#include +#include +#include +#include +#include + +// Must come last. +#include + +#define BOOST_IOSTREAMS_ASSERT_UNREACHABLE(val) \ + (BOOST_ASSERT("unreachable code" == 0), val) \ + /**/ + +namespace boost { namespace iostreams { + +namespace newline { + +const char CR = 0x0D; +const char LF = 0x0A; + + // Flags for configuring newline_filter. + +// Exactly one of the following three flags must be present. + +const int posix = 1; // Use CR as line separator. +const int mac = 2; // Use LF as line separator. +const int dos = 4; // Use CRLF as line separator. +const int mixed = 8; // Mixed line endings. +const int final_newline = 16; +const int platform_mask = posix | dos | mac; + +} // End namespace newline. + +namespace detail { + +class newline_base { +public: + bool is_posix() const + { + return !is_mixed() && (flags_ & newline::posix) != 0; + } + bool is_dos() const + { + return !is_mixed() && (flags_ & newline::dos) != 0; + } + bool is_mac() const + { + return !is_mixed() && (flags_ & newline::mac) != 0; + } + bool is_mixed_posix() const { return (flags_ & newline::posix) != 0; } + bool is_mixed_dos() const { return (flags_ & newline::dos) != 0; } + bool is_mixed_mac() const { return (flags_ & newline::mac) != 0; } + bool is_mixed() const + { + int platform = + (flags_ & newline::posix) != 0 ? + newline::posix : + (flags_ & newline::dos) != 0 ? + newline::dos : + (flags_ & newline::mac) != 0 ? + newline::mac : + 0; + return (flags_ & ~platform & newline::platform_mask) != 0; + } + bool has_final_newline() const + { + return (flags_ & newline::final_newline) != 0; + } +protected: + newline_base(int flags) : flags_(flags) { } + int flags_; +}; + +} // End namespace detail. + +class newline_error + : public BOOST_IOSTREAMS_FAILURE, public detail::newline_base +{ +private: + friend class newline_checker; + newline_error(int flags) + : BOOST_IOSTREAMS_FAILURE("bad line endings"), + detail::newline_base(flags) + { } +}; + +class newline_filter { +public: + typedef char char_type; + struct category + : dual_use, + filter_tag, + closable_tag + { }; + + explicit newline_filter(int target) : flags_(target) + { + if ( target != iostreams::newline::posix && + target != iostreams::newline::dos && + target != iostreams::newline::mac ) + { + boost::throw_exception(std::logic_error("bad flags")); + } + } + + template + int get(Source& src) + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + BOOST_ASSERT((flags_ & f_write) == 0); + flags_ |= f_read; + + if (flags_ & (f_has_LF | f_has_EOF)) { + if (flags_ & f_has_LF) + return newline(); + else + return EOF; + } + + int c = + (flags_ & f_has_CR) == 0 ? + iostreams::get(src) : + CR; + + if (c == WOULD_BLOCK ) + return WOULD_BLOCK; + + if (c == CR) { + flags_ |= f_has_CR; + + int d; + if ((d = iostreams::get(src)) == WOULD_BLOCK) + return WOULD_BLOCK; + + if (d == LF) { + flags_ &= ~f_has_CR; + return newline(); + } + + if (d == EOF) { + flags_ |= f_has_EOF; + } else { + iostreams::putback(src, d); + } + + flags_ &= ~f_has_CR; + return newline(); + } + + if (c == LF) + return newline(); + + return c; + } + + template + bool put(Sink& dest, char c) + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + BOOST_ASSERT((flags_ & f_read) == 0); + flags_ |= f_write; + + if ((flags_ & f_has_LF) != 0) + return c == LF ? + newline(dest) : + newline(dest) && this->put(dest, c); + + if (c == LF) + return newline(dest); + + if ((flags_ & f_has_CR) != 0) + return newline(dest) ? + this->put(dest, c) : + false; + + if (c == CR) { + flags_ |= f_has_CR; + return true; + } + + return iostreams::put(dest, c); + } + + template + void close(Sink& dest, BOOST_IOS::openmode) + { + if ((flags_ & f_write) != 0 && (flags_ & f_has_CR) != 0) + newline_if_sink(dest); + flags_ &= ~f_has_LF; // Restore original flags. + } +private: + + // Returns the appropriate element of a newline sequence. + int newline() + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + switch (flags_ & iostreams::newline::platform_mask) { + case iostreams::newline::posix: + return LF; + case iostreams::newline::mac: + return CR; + case iostreams::newline::dos: + if (flags_ & f_has_LF) { + flags_ &= ~f_has_LF; + return LF; + } else { + flags_ |= f_has_LF; + return CR; + } + } + return BOOST_IOSTREAMS_ASSERT_UNREACHABLE(0); + } + + // Writes a newline sequence. + template + bool newline(Sink& dest) + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + bool success = false; + switch (flags_ & iostreams::newline::platform_mask) { + case iostreams::newline::posix: + success = boost::iostreams::put(dest, LF); + break; + case iostreams::newline::mac: + success = boost::iostreams::put(dest, CR); + break; + case iostreams::newline::dos: + if ((flags_ & f_has_LF) != 0) { + if ((success = boost::iostreams::put(dest, LF))) + flags_ &= ~f_has_LF; + } else if (boost::iostreams::put(dest, CR)) { + if (!(success = boost::iostreams::put(dest, LF))) + flags_ |= f_has_LF; + } + break; + } + if (success) + flags_ &= ~f_has_CR; + return success; + } + + // Writes a newline sequence if the given device is a Sink. + template + void newline_if_sink(Device& dest) + { + typedef typename iostreams::category_of::type category; + newline_if_sink(dest, is_convertible()); + } + + template + void newline_if_sink(Sink& dest, mpl::true_) { newline(dest); } + + template + void newline_if_sink(Source&, mpl::false_) { } + + enum flags { + f_has_LF = 32768, + f_has_CR = f_has_LF << 1, + f_has_newline = f_has_CR << 1, + f_has_EOF = f_has_newline << 1, + f_read = f_has_EOF << 1, + f_write = f_read << 1 + }; + int flags_; +}; +BOOST_IOSTREAMS_PIPABLE(newline_filter, 0) + +class newline_checker : public detail::newline_base { +public: + typedef char char_type; + struct category + : dual_use_filter_tag, + closable_tag + { }; + explicit newline_checker(int target = newline::mixed) + : detail::newline_base(0), target_(target), open_(false) + { } + template + int get(Source& src) + { + using newline::CR; + using newline::LF; + + if (!open_) { + open_ = true; + source() = 0; + } + + int c; + if ((c = iostreams::get(src)) == WOULD_BLOCK) + return WOULD_BLOCK; + + // Update source flags. + if (c != EOF) + source() &= ~f_line_complete; + if ((source() & f_has_CR) != 0) { + if (c == LF) { + source() |= newline::dos; + source() |= f_line_complete; + } else { + source() |= newline::mac; + if (c == EOF) + source() |= f_line_complete; + } + } else if (c == LF) { + source() |= newline::posix; + source() |= f_line_complete; + } + source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0); + + // Check for errors. + if ( c == EOF && + (target_ & newline::final_newline) != 0 && + (source() & f_line_complete) == 0 ) + { + fail(); + } + if ( (target_ & newline::platform_mask) != 0 && + (source() & ~target_ & newline::platform_mask) != 0 ) + { + fail(); + } + + return c; + } + + template + bool put(Sink& dest, int c) + { + using iostreams::newline::CR; + using iostreams::newline::LF; + + if (!open_) { + open_ = true; + source() = 0; + } + + if (!iostreams::put(dest, c)) + return false; + + // Update source flags. + source() &= ~f_line_complete; + if ((source() & f_has_CR) != 0) { + if (c == LF) { + source() |= newline::dos; + source() |= f_line_complete; + } else { + source() |= newline::mac; + } + } else if (c == LF) { + source() |= newline::posix; + source() |= f_line_complete; + } + source() = (source() & ~f_has_CR) | (c == CR ? f_has_CR : 0); + + // Check for errors. + if ( (target_ & newline::platform_mask) != 0 && + (source() & ~target_ & newline::platform_mask) != 0 ) + { + fail(); + } + + return true; + } + + template + void close(Sink&, BOOST_IOS::openmode) + { + using iostreams::newline::final_newline; + + // Update final_newline flag. + if ( (source() & f_has_CR) != 0 || + (source() & f_line_complete) != 0 ) + { + source() |= final_newline; + } + + // Clear non-sticky flags. + source() &= ~(f_has_CR | f_line_complete); + + // Check for errors. + if ( (target_ & final_newline) != 0 && + (source() & final_newline) == 0 ) + { + fail(); + } + } +private: + void fail() { boost::throw_exception(newline_error(source())); } + int& source() { return flags_; } + int source() const { return flags_; } + + enum flags { + f_has_CR = 32768, + f_line_complete = f_has_CR << 1 + }; + + int target_; // Represents expected input. + bool open_; +}; +BOOST_IOSTREAMS_PIPABLE(newline_checker, 0) + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/regex.hpp b/boost/iostreams/filter/regex.hpp new file mode 100644 index 0000000..e943553 --- /dev/null +++ b/boost/iostreams/filter/regex.hpp @@ -0,0 +1,98 @@ +// (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 BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // allocator. +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +template< typename Ch, + typename Tr = regex_traits, + typename Alloc = std::allocator > +class basic_regex_filter : public aggregate_filter { +private: + typedef aggregate_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + typedef std::basic_string string_type; + typedef basic_regex regex_type; + typedef regex_constants::match_flag_type flag_type; + typedef match_results match_type; + typedef function1 formatter; + + basic_regex_filter( const regex_type& re, + const formatter& replace, + flag_type flags = regex_constants::match_default ) + : re_(re), replace_(replace), flags_(flags) { } + basic_regex_filter( const regex_type& re, + const string_type& fmt, + flag_type flags = regex_constants::match_default, + flag_type fmt_flags = regex_constants::format_default ) + : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { } + basic_regex_filter( const regex_type& re, + const char_type* fmt, + flag_type flags = regex_constants::match_default, + flag_type fmt_flags = regex_constants::format_default ) + : re_(re), replace_(simple_formatter(fmt, fmt_flags)), flags_(flags) { } +private: + typedef typename base_type::vector_type vector_type; + void do_filter(const vector_type& src, vector_type& dest) + { + typedef regex_iterator iterator; + if (src.empty()) + return; + iterator first(&src[0], &src[0] + src.size(), re_, flags_); + iterator last; + const Ch* suffix = 0; + for (; first != last; ++first) { + dest.insert( dest.end(), + first->prefix().first, + first->prefix().second ); + string_type replacement = replace_(*first); + dest.insert( dest.end(), + replacement.begin(), + replacement.end() ); + suffix = first->suffix().first; + } + if (suffix) { + dest.insert(dest.end(), suffix, &src[0] + src.size()); + } else { + dest.insert(dest.end(), &src[0], &src[0] + src.size()); + } + } + struct simple_formatter { + simple_formatter(const string_type& fmt, flag_type fmt_flags) + : fmt_(fmt), fmt_flags_(fmt_flags) { } + string_type operator() (const match_type& match) const + { return match.format(fmt_, fmt_flags_); } + string_type fmt_; + flag_type fmt_flags_; + }; + regex_type re_; + formatter replace_; + flag_type flags_; +}; +BOOST_IOSTREAMS_PIPABLE(basic_regex_filter, 3) + +typedef basic_regex_filter regex_filter; +typedef basic_regex_filter wregex_filter; + + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/stdio.hpp b/boost/iostreams/filter/stdio.hpp new file mode 100644 index 0000000..5ad921b --- /dev/null +++ b/boost/iostreams/filter/stdio.hpp @@ -0,0 +1,84 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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. + +// Based on the work of Christopher Diggins. + +#ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // allocator. +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +} // End namespace detail. + +template > +class basic_stdio_filter : public aggregate_filter { +private: + typedef aggregate_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + typedef typename base_type::vector_type vector_type; +private: + static std::istream& standard_input(char*) { return std::cin; } + static std::ostream& standard_output(char*) { return std::cout; } +#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS + static std::wistream& standard_input(wchar_t*) { return std::wcin; } + static std::wostream& standard_output(wchar_t*) { return std::wcout; } +#endif // BOOST_IOSTREAMS_NO_WIDE_STREAMS + + struct scoped_redirector { // Thanks to Maxim Egorushkin. + typedef BOOST_IOSTREAMS_CHAR_TRAITS(Ch) traits_type; + typedef BOOST_IOSTREAMS_BASIC_IOS(Ch, traits_type) ios_type; + typedef BOOST_IOSTREAMS_BASIC_STREAMBUF(Ch, traits_type) streambuf_type; + scoped_redirector( ios_type& ios, + streambuf_type* newbuf ) + : ios_(ios), old_(ios.rdbuf(newbuf)) + { } + ~scoped_redirector() { ios_.rdbuf(old_); } + scoped_redirector& operator=(const scoped_redirector&); + ios_type& ios_; + streambuf_type* old_; + }; + + virtual void do_filter() = 0; + virtual void do_filter(const vector_type& src, vector_type& dest) + { + stream_buffer< basic_array_source > + srcbuf(&src[0], &src[0] + src.size()); + stream_buffer< back_insert_device > + destbuf(iostreams::back_inserter(dest)); + scoped_redirector redirect_input(standard_input((Ch*)0), &srcbuf); + scoped_redirector redirect_output(standard_output((Ch*)0), &destbuf); + do_filter(); + } +}; +BOOST_IOSTREAMS_PIPABLE(basic_stdio_filter, 2) + +typedef basic_stdio_filter stdio_filter; +typedef basic_stdio_filter wstdio_wfilter; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/symmetric.hpp b/boost/iostreams/filter/symmetric.hpp new file mode 100644 index 0000000..f18089f --- /dev/null +++ b/boost/iostreams/filter/symmetric.hpp @@ -0,0 +1,311 @@ +// (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. + +// Contains the definitions of the class templates symmetric_filter, +// which models DualUseFilter based on a model of the Symmetric Filter. + +// +// Roughly, a Symmetric Filter is a class type with the following interface: +// +// struct symmetric_filter { +// typedef xxx char_type; +// +// bool filter( const char*& begin_in, const char* end_in, +// char*& begin_out, char* end_out, bool flush ) +// { +// // Consume as many characters as possible from the interval +// // [begin_in, end_in), without exhausting the output range +// // [begin_out, end_out). If flush is true, write as mush output +// // as possible. +// // A return value of true indicates that filter should be called +// // again. More precisely, if flush is false, a return value of +// // false indicates that the natural end of stream has been reached +// // and that all filtered data has been forwarded; if flush is +// // true, a return value of false indicates that all filtered data +// // has been forwarded. +// } +// void close() { /* Reset filter's state. */ } +// }; +// +// Symmetric Filter filters need not be CopyConstructable. +// + +#ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED +#define BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // allocator. +#include // BOOST_DEDUCED_TYPENAME. +#include +#include // buffer size. +#include +#include +#include +#include // streamsize. +#include +#include +#include // read, write. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +template< typename SymmetricFilter, + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +class symmetric_filter { +public: + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + typedef std::basic_string string_type; + struct category + : dual_use, + filter_tag, + multichar_tag, + closable_tag + { }; + + // Expands to a sequence of ctors which forward to impl. + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \ + explicit symmetric_filter( \ + std::streamsize buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \ + : pimpl_(new impl(buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_PARAMS(n, t))) \ + { BOOST_ASSERT(buffer_size > 0); } \ + /**/ + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) + #include BOOST_PP_LOCAL_ITERATE() + #undef BOOST_PP_LOCAL_MACRO + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + using namespace std; + if (!(state() & f_read)) + begin_read(); + + buffer_type& buf = pimpl_->buf_; + int status = (state() & f_eof) != 0 ? f_eof : f_good; + char_type *next_s = s, + *end_s = s + n; + while (true) + { + // Invoke filter if there are unconsumed characters in buffer or if + // filter must be flushed. + bool flush = status == f_eof; + if (buf.ptr() != buf.eptr() || flush) { + const char_type* next = buf.ptr(); + bool done = + !filter().filter(next, buf.eptr(), next_s, end_s, flush); + buf.ptr() = buf.data() + (next - buf.data()); + if (done) + return detail::check_eof( + static_cast(next_s - s) + ); + } + + // If no more characters are available without blocking, or + // if read request has been satisfied, return. + if ( (status == f_would_block && buf.ptr() == buf.eptr()) || + next_s == end_s ) + { + return static_cast(next_s - s); + } + + // Fill buffer. + if (status == f_good) + status = fill(src); + } + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + if (!(state() & f_write)) + begin_write(); + + buffer_type& buf = pimpl_->buf_; + const char_type *next_s, *end_s; + for (next_s = s, end_s = s + n; next_s != end_s; ) { + if (buf.ptr() == buf.eptr() && !flush(snk)) + break; + if(!filter().filter(next_s, end_s, buf.ptr(), buf.eptr(), false)) { + flush(snk); + break; + } + } + return static_cast(next_s - s); + } + + template + void close(Sink& snk, BOOST_IOS::openmode mode) + { + if (mode == BOOST_IOS::out) { + + if (!(state() & f_write)) + begin_write(); + + // Repeatedly invoke filter() with no input. + try { + buffer_type& buf = pimpl_->buf_; + char_type dummy; + const char_type* end = &dummy; + bool again = true; + while (again) { + if (buf.ptr() != buf.eptr()) + again = filter().filter( end, end, buf.ptr(), + buf.eptr(), true ); + flush(snk); + } + } catch (...) { + try { close_impl(); } catch (...) { } + throw; + } + close_impl(); + } else { + close_impl(); + } + } + SymmetricFilter& filter() { return *pimpl_; } + string_type unconsumed_input() const; + +// Give impl access to buffer_type on Tru64 +#if !BOOST_WORKAROUND(__DECCXX_VER, BOOST_TESTED_AT(60590042)) + private: +#endif + typedef detail::buffer buffer_type; +private: + buffer_type& buf() { return pimpl_->buf_; } + const buffer_type& buf() const { return pimpl_->buf_; } + int& state() { return pimpl_->state_; } + void begin_read(); + void begin_write(); + + template + int fill(Source& src) + { + std::streamsize amt = iostreams::read(src, buf().data(), buf().size()); + if (amt == -1) { + state() |= f_eof; + return f_eof; + } + buf().set(0, amt); + return amt != 0 ? f_good : f_would_block; + } + + // Attempts to write the contents of the buffer the given Sink. + // Returns true if at least on character was written. + template + bool flush(Sink& snk) + { + typedef typename iostreams::category_of::type category; + typedef is_convertible can_write; + return flush(snk, can_write()); + } + + template + bool flush(Sink& snk, mpl::true_) + { + std::streamsize amt = + static_cast(buf().ptr() - buf().data()); + std::streamsize result = + boost::iostreams::write(snk, buf().data(), amt); + if (result < amt && result > 0) + traits_type::move(buf().data(), buf().data() + result, amt - result); + buf().set(amt - result, buf().size()); + return result != 0; + } + + template + bool flush(Sink&, mpl::false_) { return true;} + + void close_impl(); + + enum flag_type { + f_read = 1, + f_write = f_read << 1, + f_eof = f_write << 1, + f_good, + f_would_block + }; + + struct impl : SymmetricFilter { + + // Expands to a sequence of ctors which forward to SymmetricFilter. + #define BOOST_PP_LOCAL_MACRO(n) \ + BOOST_IOSTREAMS_TEMPLATE_PARAMS(n, T) \ + impl( std::streamsize buffer_size BOOST_PP_COMMA_IF(n) \ + BOOST_PP_ENUM_BINARY_PARAMS(n, const T, &t) ) \ + : SymmetricFilter(BOOST_PP_ENUM_PARAMS(n, t)), \ + buf_(buffer_size), state_(0) \ + { } \ + /**/ + #define BOOST_PP_LOCAL_LIMITS (0, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY) + #include BOOST_PP_LOCAL_ITERATE() + #undef BOOST_PP_LOCAL_MACRO + + buffer_type buf_; + int state_; + }; + + shared_ptr pimpl_; +}; +BOOST_IOSTREAMS_PIPABLE(symmetric_filter, 2) + +//------------------Implementation of symmetric_filter----------------// + +template +void symmetric_filter::begin_read() +{ + BOOST_ASSERT(!(state() & f_write)); + state() |= f_read; + buf().set(0, 0); +} + +template +void symmetric_filter::begin_write() +{ + BOOST_ASSERT(!(state() & f_read)); + state() |= f_write; + buf().set(0, buf().size()); +} + +template +void symmetric_filter::close_impl() +{ + state() = 0; + buf().set(0, 0); + filter().close(); +} + +template +typename symmetric_filter::string_type +symmetric_filter::unconsumed_input() const +{ return string_type(buf().ptr(), buf().eptr()); } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_SYMMETRIC_FILTER_HPP_INCLUDED diff --git a/boost/iostreams/filter/test.hpp b/boost/iostreams/filter/test.hpp new file mode 100644 index 0000000..c5039c8 --- /dev/null +++ b/boost/iostreams/filter/test.hpp @@ -0,0 +1,319 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC,put size_t in std. +#include +#include // min. +#include // size_t. +#if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ +# include // rand. +#endif +#include // memcpy, strlen. +#include +#include +#include +#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ +# include +# include +#endif +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef memcpy +#undef rand +#undef strlen + +#if defined(BOOST_NO_STDC_NAMESPACE) && !defined(__LIBCOMO__) +namespace std { + using ::memcpy; + using ::strlen; + #if BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) || \ + BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ + using ::rand; + #endif +} +#endif + +namespace boost { namespace iostreams { + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_string, std::basic_string, 3) + +const std::streamsize default_increment = 5; + +#if !BOOST_WORKAROUND(BOOST_BORLANDC, BOOST_TESTED_AT(0x564)) && \ + !BOOST_WORKAROUND(__MWERKS__, <= 0x3003) \ + /**/ + std::streamsize rand(std::streamsize inc) + { + static rand48 random_gen; + static uniform_smallint random_dist(0, static_cast(inc)); + return random_dist(random_gen); + } +#else + std::streamsize rand(std::streamsize inc) + { + return (std::rand() * inc + 1) / RAND_MAX; + } +#endif + +class non_blocking_source { +public: + typedef char char_type; + struct category + : source_tag, + peekable_tag + { }; + explicit non_blocking_source( const std::string& data, + std::streamsize inc = default_increment ) + : data_(data), inc_(inc), pos_(0) + { } + std::streamsize read(char* s, std::streamsize n) + { + using namespace std; + if (pos_ == static_cast(data_.size())) + return -1; + streamsize avail = + (std::min) (n, static_cast(data_.size() - pos_)); + streamsize amt = (std::min) (rand(inc_), avail); + if (amt) + memcpy(s, data_.c_str() + pos_, static_cast(amt)); + pos_ += amt; + return amt; + } + + bool putback(char c) + { + if (pos_ > 0) { + data_[static_cast(--pos_)] = c; + return true; + } + return false; + } +private: + std::string data_; + std::streamsize inc_, pos_; +}; + +class non_blocking_sink : public sink { +public: + non_blocking_sink( std::string& dest, + std::streamsize inc = default_increment ) + : dest_(dest), inc_(inc) + { } + std::streamsize write(const char* s, std::streamsize n) + { + std::streamsize amt = (std::min) (rand(inc_), n); + dest_.insert(dest_.end(), s, s + amt); + return amt; + } +private: + non_blocking_sink& operator=(const non_blocking_sink&); + std::string& dest_; + std::streamsize inc_; +}; + +//--------------Definition of test_input_filter-------------------------------// + +template +bool test_input_filter( Filter filter, + const std::string& input, + const std::string& output, + mpl::true_ ) +{ + for ( int inc = default_increment; + inc < default_increment * 40; + inc += default_increment ) + { + non_blocking_source src(input, inc); + std::string dest; + iostreams::copy(compose(filter, src), iostreams::back_inserter(dest)); + if (dest != output) + return false; + } + return true; +} + +template +bool test_input_filter( Filter filter, + const Source1& input, + const Source2& output, + mpl::false_ ) +{ + std::string in; + std::string out; + iostreams::copy(input, iostreams::back_inserter(in)); + iostreams::copy(output, iostreams::back_inserter(out)); + return test_input_filter(filter, in, out); +} + +template +bool test_input_filter( Filter filter, + const Source1& input, + const Source2& output ) +{ + // Use tag dispatch to compensate for bad overload resolution. + return test_input_filter( filter, input, output, + is_string() ); +} + +//--------------Definition of test_output_filter------------------------------// + +template +bool test_output_filter( Filter filter, + const std::string& input, + const std::string& output, + mpl::true_ ) +{ + for ( int inc = default_increment; + inc < default_increment * 40; + inc += default_increment ) + { + array_source src(input.data(), input.data() + input.size()); + std::string dest; + iostreams::copy(src, compose(filter, non_blocking_sink(dest, inc))); + if (dest != output ) + return false; + } + return true; +} + +template +bool test_output_filter( Filter filter, + const Source1& input, + const Source2& output, + mpl::false_ ) +{ + std::string in; + std::string out; + iostreams::copy(input, iostreams::back_inserter(in)); + iostreams::copy(output, iostreams::back_inserter(out)); + return test_output_filter(filter, in, out); +} + +template +bool test_output_filter( Filter filter, + const Source1& input, + const Source2& output ) +{ + // Use tag dispatch to compensate for bad overload resolution. + return test_output_filter( filter, input, output, + is_string() ); +} + +//--------------Definition of test_filter_pair--------------------------------// + +template +bool test_filter_pair( OutputFilter out, + InputFilter in, + const std::string& data, + mpl::true_ ) +{ + for ( int inc = default_increment; + inc <= default_increment * 40; + inc += default_increment ) + { + { + array_source src(data.data(), data.data() + data.size()); + std::string temp; + std::string dest; + iostreams::copy(src, compose(out, non_blocking_sink(temp, inc))); + iostreams::copy( + compose(in, non_blocking_source(temp, inc)), + iostreams::back_inserter(dest) + ); + if (dest != data) + return false; + } + { + array_source src(data.data(), data.data() + data.size()); + std::string temp; + std::string dest; + iostreams::copy(src, compose(out, non_blocking_sink(temp, inc))); + // truncate the file, this should not loop, it may throw + // std::ios_base::failure, which we swallow. + try { + temp.resize(temp.size() / 2); + iostreams::copy( + compose(in, non_blocking_source(temp, inc)), + iostreams::back_inserter(dest) + ); + } catch(std::ios_base::failure&) {} + } + { + array_source src(data.data(), data.data() + data.size()); + std::string temp; + std::string dest; + iostreams::copy(compose(out, src), non_blocking_sink(temp, inc)); + iostreams::copy( + non_blocking_source(temp, inc), + compose(in, iostreams::back_inserter(dest)) + ); + if (dest != data) + return false; + } + { + array_source src(data.data(), data.data() + data.size()); + std::string temp; + std::string dest; + iostreams::copy(compose(out, src), non_blocking_sink(temp, inc)); + // truncate the file, this should not loop, it may throw + // std::ios_base::failure, which we swallow. + try { + temp.resize(temp.size() / 2); + iostreams::copy( + non_blocking_source(temp, inc), + compose(in, iostreams::back_inserter(dest)) + ); + } catch(std::ios_base::failure&) {} + } + } + return true; +} + +template +bool test_filter_pair( OutputFilter out, + InputFilter in, + const Source& data, + mpl::false_ ) +{ + std::string str; + iostreams::copy(data, iostreams::back_inserter(str)); + return test_filter_pair(out, in, str); +} + +template +bool test_filter_pair( OutputFilter out, + InputFilter in, + const Source& data ) +{ + // Use tag dispatch to compensate for bad overload resolution. + return test_filter_pair(out, in, data, is_string()); +} + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_FILTER_TEST_HPP_INCLUDED diff --git a/boost/iostreams/filter/zlib.hpp b/boost/iostreams/filter/zlib.hpp new file mode 100644 index 0000000..e57870a --- /dev/null +++ b/boost/iostreams/filter/zlib.hpp @@ -0,0 +1,431 @@ +// (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. + +// Note: custom allocators are not supported on VC6, since that compiler +// had trouble finding the function zlib_base::do_init. + +#ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED +#define BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // streamsize. +#include // allocator, bad_alloc. +#include +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include // uint*_t +#include +#include // buffer size. +#include +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4275 4231 4660) // Dependencies not exported. +#endif +#include + +namespace boost { namespace iostreams { + +namespace zlib { + // Typedefs + +typedef uint32_t uint; +typedef uint8_t byte; +typedef uint32_t ulong; + +// Prefix 'x' prevents symbols from being redefined when Z_PREFIX is defined +typedef void* (*xalloc_func)(void*, zlib::uint, zlib::uint); +typedef void (*xfree_func)(void*, void*); + + // Compression levels + +BOOST_IOSTREAMS_DECL extern const int no_compression; +BOOST_IOSTREAMS_DECL extern const int best_speed; +BOOST_IOSTREAMS_DECL extern const int best_compression; +BOOST_IOSTREAMS_DECL extern const int default_compression; + + // Compression methods + +BOOST_IOSTREAMS_DECL extern const int deflated; + + // Compression strategies + +BOOST_IOSTREAMS_DECL extern const int default_strategy; +BOOST_IOSTREAMS_DECL extern const int filtered; +BOOST_IOSTREAMS_DECL extern const int huffman_only; + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int okay; +BOOST_IOSTREAMS_DECL extern const int stream_end; +BOOST_IOSTREAMS_DECL extern const int stream_error; +BOOST_IOSTREAMS_DECL extern const int version_error; +BOOST_IOSTREAMS_DECL extern const int data_error; +BOOST_IOSTREAMS_DECL extern const int mem_error; +BOOST_IOSTREAMS_DECL extern const int buf_error; + + // Flush codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int no_flush; +BOOST_IOSTREAMS_DECL extern const int sync_flush; + + // Code for current OS + +//BOOST_IOSTREAMS_DECL extern const int os_code; + + // Null pointer constant. + +const int null = 0; + + // Default values + +const int default_window_bits = 15; +const int default_mem_level = 8; +const bool default_crc = false; +const bool default_noheader = false; + +} // End namespace zlib. + +// +// Class name: zlib_params. +// Description: Encapsulates the parameters passed to deflateInit2 +// and inflateInit2 to customize compression and decompression. +// +struct zlib_params { + + // Non-explicit constructor. + zlib_params( int level_ = zlib::default_compression, + int method_ = zlib::deflated, + int window_bits_ = zlib::default_window_bits, + int mem_level_ = zlib::default_mem_level, + int strategy_ = zlib::default_strategy, + bool noheader_ = zlib::default_noheader, + bool calculate_crc_ = zlib::default_crc ) + : level(level_), method(method_), window_bits(window_bits_), + mem_level(mem_level_), strategy(strategy_), + noheader(noheader_), calculate_crc(calculate_crc_) + { } + int level; + int method; + int window_bits; + int mem_level; + int strategy; + bool noheader; + bool calculate_crc; +}; + +// +// Class name: zlib_error. +// Description: Subclass of std::ios::failure thrown to indicate +// zlib errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL zlib_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit zlib_error(int error); + int error() const { return error_; } + static void check BOOST_PREVENT_MACRO_SUBSTITUTION(int error); +private: + int error_; +}; + +namespace detail { + +template +struct zlib_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Alloc::template rebind::other type; +#else + typedef typename std::allocator_traits::template rebind_alloc type; +#endif +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME zlib_allocator_traits::type > +struct zlib_allocator : private Base { +private: +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + typedef typename Base::size_type size_type; +#else + typedef typename std::allocator_traits::size_type size_type; +#endif +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename zlib_allocator_traits::type allocator_type; + static void* allocate(void* self, zlib::uint items, zlib::uint size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL zlib_base { +public: + typedef char char_type; +protected: + zlib_base(); + ~zlib_base(); + void* stream() { return stream_; } + template + void init( const zlib_params& p, + bool compress, + zlib_allocator& zalloc ) + { + bool custom = zlib_allocator::custom; + do_init( p, compress, + custom ? zlib_allocator::allocate : 0, + custom ? zlib_allocator::deallocate : 0, + &zalloc ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after( const char*& src_begin, char*& dest_begin, + bool compress ); + int xdeflate(int flush); // Prefix 'x' prevents symbols from being + int xinflate(int flush); // redefined when Z_PREFIX is defined + void reset(bool compress, bool realloc); +public: + zlib::ulong crc() const { return crc_; } + int total_in() const { return total_in_; } + int total_out() const { return total_out_; } +private: + void do_init( const zlib_params& p, bool compress, + zlib::xalloc_func, + zlib::xfree_func, + void* derived ); + void* stream_; // Actual type: z_stream*. + bool calculate_crc_; + zlib::ulong crc_; + zlib::ulong crc_imp_; + int total_in_; + int total_out_; +}; + +// +// Template name: zlib_compressor_impl +// Description: Model of C-Style Filte implementing compression by +// delegating to the zlib function deflate. +// +template > +class zlib_compressor_impl : public zlib_base, public zlib_allocator { +public: + zlib_compressor_impl(const zlib_params& = zlib::default_compression); + ~zlib_compressor_impl(); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +}; + +// +// Template name: zlib_compressor +// Description: Model of C-Style Filte implementing decompression by +// delegating to the zlib function inflate. +// +template > +class zlib_decompressor_impl : public zlib_base, public zlib_allocator { +public: + zlib_decompressor_impl(const zlib_params&); + zlib_decompressor_impl(int window_bits = zlib::default_window_bits); + ~zlib_decompressor_impl(); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); + bool eof() const { return eof_; } +private: + bool eof_; +}; + +} // End namespace detail. + +// +// Template name: zlib_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using zlib. +// +template > +struct basic_zlib_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zlib_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zlib_compressor( const zlib_params& = zlib::default_compression, + std::streamsize buffer_size = default_device_buffer_size ); + zlib::ulong crc() { return this->filter().crc(); } + int total_in() { return this->filter().total_in(); } +}; +BOOST_IOSTREAMS_PIPABLE(basic_zlib_compressor, 1) + +typedef basic_zlib_compressor<> zlib_compressor; + +// +// Template name: zlib_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using zlib. +// +template > +struct basic_zlib_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zlib_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zlib_decompressor( int window_bits = zlib::default_window_bits, + std::streamsize buffer_size = default_device_buffer_size ); + basic_zlib_decompressor( const zlib_params& p, + std::streamsize buffer_size = default_device_buffer_size ); + zlib::ulong crc() { return this->filter().crc(); } + int total_out() { return this->filter().total_out(); } + bool eof() { return this->filter().eof(); } +}; +BOOST_IOSTREAMS_PIPABLE(basic_zlib_decompressor, 1) + +typedef basic_zlib_decompressor<> zlib_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of zlib_allocator--------------------------// + +namespace detail { + +template +void* zlib_allocator::allocate + (void* self, zlib::uint items, zlib::uint size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void zlib_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of zlib_compressor_impl--------------------// + +template +zlib_compressor_impl::zlib_compressor_impl(const zlib_params& p) +{ init(p, true, static_cast&>(*this)); } + +template +zlib_compressor_impl::~zlib_compressor_impl() +{ reset(true, false); } + +template +bool zlib_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = xdeflate(flush ? zlib::finish : zlib::no_flush); + after(src_begin, dest_begin, true); + zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + return result != zlib::stream_end; +} + +template +void zlib_compressor_impl::close() { reset(true, true); } + +//------------------Implementation of zlib_decompressor_impl------------------// + +template +zlib_decompressor_impl::zlib_decompressor_impl(const zlib_params& p) + : eof_(false) +{ init(p, false, static_cast&>(*this)); } + +template +zlib_decompressor_impl::~zlib_decompressor_impl() +{ reset(false, false); } + +template +zlib_decompressor_impl::zlib_decompressor_impl(int window_bits) +{ + zlib_params p; + p.window_bits = window_bits; + init(p, false, static_cast&>(*this)); +} + +template +bool zlib_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool /* flush */ ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = xinflate(zlib::sync_flush); + after(src_begin, dest_begin, false); + zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + return !(eof_ = result == zlib::stream_end); +} + +template +void zlib_decompressor_impl::close() { + eof_ = false; + reset(false, true); +} + +} // End namespace detail. + +//------------------Implementation of zlib_decompressor-----------------------// + +template +basic_zlib_compressor::basic_zlib_compressor + (const zlib_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//------------------Implementation of zlib_decompressor-----------------------// + +template +basic_zlib_decompressor::basic_zlib_decompressor + (int window_bits, std::streamsize buffer_size) + : base_type(buffer_size, window_bits) { } + +template +basic_zlib_decompressor::basic_zlib_decompressor + (const zlib_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_ZLIB_HPP_INCLUDED diff --git a/boost/iostreams/filter/zstd.hpp b/boost/iostreams/filter/zstd.hpp new file mode 100644 index 0000000..176799d --- /dev/null +++ b/boost/iostreams/filter/zstd.hpp @@ -0,0 +1,363 @@ +// (C) Copyright Reimar Döffinger 2018. +// Based on zstd.hpp by: +// (C) Copyright Milan Svoboda 2008. +// 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_ZSTD_HPP_INCLUDED +#define BOOST_IOSTREAMS_ZSTD_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // streamsize. +#include // allocator, bad_alloc. +#include +#include // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM. +#include +#include // buffer size. +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include + +// Must come last. +#ifdef BOOST_MSVC +# pragma warning(push) +# pragma warning(disable:4251 4231 4660) // Dependencies not exported. +#endif +#include + +namespace boost { namespace iostreams { + +namespace zstd { + +typedef void* (*alloc_func)(void*, size_t, size_t); +typedef void (*free_func)(void*, void*); + + // Compression levels + +BOOST_IOSTREAMS_DECL extern const uint32_t best_speed; +BOOST_IOSTREAMS_DECL extern const uint32_t best_compression; +BOOST_IOSTREAMS_DECL extern const uint32_t default_compression; + + // Status codes + +BOOST_IOSTREAMS_DECL extern const int okay; +BOOST_IOSTREAMS_DECL extern const int stream_end; + + // Flush codes + +BOOST_IOSTREAMS_DECL extern const int finish; +BOOST_IOSTREAMS_DECL extern const int flush; +BOOST_IOSTREAMS_DECL extern const int run; + + // Code for current OS + + // Null pointer constant. + +const int null = 0; + + // Default values + +} // End namespace zstd. + +// +// Class name: zstd_params. +// Description: Encapsulates the parameters passed to zstddec_init +// to customize compression and decompression. +// +struct zstd_params { + + // Non-explicit constructor. + zstd_params( uint32_t level = zstd::default_compression ) + : level(level) + { } + uint32_t level; +}; + +// +// Class name: zstd_error. +// Description: Subclass of std::ios::failure thrown to indicate +// zstd errors other than out-of-memory conditions. +// +class BOOST_IOSTREAMS_DECL zstd_error : public BOOST_IOSTREAMS_FAILURE { +public: + explicit zstd_error(size_t error); + int error() const { return error_; } + static void check BOOST_PREVENT_MACRO_SUBSTITUTION(size_t error); +private: + size_t error_; +}; + +namespace detail { + +template +struct zstd_allocator_traits { +#ifndef BOOST_NO_STD_ALLOCATOR +#if defined(BOOST_NO_CXX11_ALLOCATOR) + typedef typename Alloc::template rebind::other type; +#else + typedef typename std::allocator_traits::template rebind_alloc type; +#endif +#else + typedef std::allocator type; +#endif +}; + +template< typename Alloc, + typename Base = // VC6 workaround (C2516) + BOOST_DEDUCED_TYPENAME zstd_allocator_traits::type > +struct zstd_allocator : private Base { +private: +#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR) + typedef typename Base::size_type size_type; +#else + typedef typename std::allocator_traits::size_type size_type; +#endif +public: + BOOST_STATIC_CONSTANT(bool, custom = + (!is_same, Base>::value)); + typedef typename zstd_allocator_traits::type allocator_type; + static void* allocate(void* self, size_t items, size_t size); + static void deallocate(void* self, void* address); +}; + +class BOOST_IOSTREAMS_DECL zstd_base { +public: + typedef char char_type; +protected: + zstd_base(); + ~zstd_base(); + template + void init( const zstd_params& p, + bool compress, + zstd_allocator& zalloc ) + { + bool custom = zstd_allocator::custom; + do_init( p, compress, + custom ? zstd_allocator::allocate : 0, + custom ? zstd_allocator::deallocate : 0, + &zalloc ); + } + void before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ); + void after( const char*& src_begin, char*& dest_begin, + bool compress ); + int deflate(int action); + int inflate(int action); + void reset(bool compress, bool realloc); +private: + void do_init( const zstd_params& p, bool compress, + zstd::alloc_func, + zstd::free_func, + void* derived ); + void* cstream_; // Actual type: ZSTD_CStream * + void* dstream_; // Actual type: ZSTD_DStream * + void* in_; // Actual type: ZSTD_inBuffer * + void* out_; // Actual type: ZSTD_outBuffer * + int eof_; + uint32_t level; +}; + +// +// Template name: zstd_compressor_impl +// Description: Model of C-Style Filter implementing compression by +// delegating to the zstd function deflate. +// +template > +class zstd_compressor_impl : public zstd_base, public zstd_allocator { +public: + zstd_compressor_impl(const zstd_params& = zstd::default_compression); + ~zstd_compressor_impl(); + bool filter( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ); + void close(); +}; + +// +// Template name: zstd_compressor_impl +// Description: Model of C-Style Filte implementing decompression by +// delegating to the zstd function inflate. +// +template > +class zstd_decompressor_impl : public zstd_base, public zstd_allocator { +public: + zstd_decompressor_impl(const zstd_params&); + zstd_decompressor_impl(); + ~zstd_decompressor_impl(); + bool filter( const char*& begin_in, const char* end_in, + char*& begin_out, char* end_out, bool flush ); + void close(); +}; + +} // End namespace detail. + +// +// Template name: zstd_compressor +// Description: Model of InputFilter and OutputFilter implementing +// compression using zstd. +// +template > +struct basic_zstd_compressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zstd_compressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zstd_compressor( const zstd_params& = zstd::default_compression, + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_zstd_compressor, 1) + +typedef basic_zstd_compressor<> zstd_compressor; + +// +// Template name: zstd_decompressor +// Description: Model of InputFilter and OutputFilter implementing +// decompression using zstd. +// +template > +struct basic_zstd_decompressor + : symmetric_filter, Alloc> +{ +private: + typedef detail::zstd_decompressor_impl impl_type; + typedef symmetric_filter base_type; +public: + typedef typename base_type::char_type char_type; + typedef typename base_type::category category; + basic_zstd_decompressor( std::streamsize buffer_size = default_device_buffer_size ); + basic_zstd_decompressor( const zstd_params& p, + std::streamsize buffer_size = default_device_buffer_size ); +}; +BOOST_IOSTREAMS_PIPABLE(basic_zstd_decompressor, 1) + +typedef basic_zstd_decompressor<> zstd_decompressor; + +//----------------------------------------------------------------------------// + +//------------------Implementation of zstd_allocator--------------------------// + +namespace detail { + +template +void* zstd_allocator::allocate + (void* self, size_t items, size_t size) +{ + size_type len = items * size; + char* ptr = + static_cast(self)->allocate + (len + sizeof(size_type) + #if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) + , (char*)0 + #endif + ); + *reinterpret_cast(ptr) = len; + return ptr + sizeof(size_type); +} + +template +void zstd_allocator::deallocate(void* self, void* address) +{ + char* ptr = reinterpret_cast(address) - sizeof(size_type); + size_type len = *reinterpret_cast(ptr) + sizeof(size_type); + static_cast(self)->deallocate(ptr, len); +} + +//------------------Implementation of zstd_compressor_impl--------------------// + +template +zstd_compressor_impl::zstd_compressor_impl(const zstd_params& p) +{ init(p, true, static_cast&>(*this)); } + +template +zstd_compressor_impl::~zstd_compressor_impl() +{ reset(true, false); } + +template +bool zstd_compressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = deflate(flush ? zstd::finish : zstd::run); + after(src_begin, dest_begin, true); + return result != zstd::stream_end; +} + +template +void zstd_compressor_impl::close() { reset(true, true); } + +//------------------Implementation of zstd_decompressor_impl------------------// + +template +zstd_decompressor_impl::zstd_decompressor_impl(const zstd_params& p) +{ init(p, false, static_cast&>(*this)); } + +template +zstd_decompressor_impl::~zstd_decompressor_impl() +{ reset(false, false); } + +template +zstd_decompressor_impl::zstd_decompressor_impl() +{ + zstd_params p; + init(p, false, static_cast&>(*this)); +} + +template +bool zstd_decompressor_impl::filter + ( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end, bool flush ) +{ + before(src_begin, src_end, dest_begin, dest_end); + int result = inflate(flush ? zstd::finish : zstd::run); + after(src_begin, dest_begin, false); + return result != zstd::stream_end; +} + +template +void zstd_decompressor_impl::close() { reset(false, true); } + +} // End namespace detail. + +//------------------Implementation of zstd_compressor-----------------------// + +template +basic_zstd_compressor::basic_zstd_compressor + (const zstd_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//------------------Implementation of zstd_decompressor-----------------------// + +template +basic_zstd_decompressor::basic_zstd_decompressor + (std::streamsize buffer_size) + : base_type(buffer_size) { } + +template +basic_zstd_decompressor::basic_zstd_decompressor + (const zstd_params& p, std::streamsize buffer_size) + : base_type(buffer_size, p) { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // Pops abi_suffix.hpp pragmas. +#ifdef BOOST_MSVC +# pragma warning(pop) +#endif + +#endif // #ifndef BOOST_IOSTREAMS_ZSTD_HPP_INCLUDED diff --git a/boost/iostreams/filtering_stream.hpp b/boost/iostreams/filtering_stream.hpp new file mode 100644 index 0000000..8621ef9 --- /dev/null +++ b/boost/iostreams/filtering_stream.hpp @@ -0,0 +1,187 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2004-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 BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // allocator. +#include +#include +#include // standard streams. +#include +#include +#include // pubsync. +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +//--------------Definition of filtered_istream--------------------------------// + +namespace detail { + +template +struct filtering_stream_traits { + typedef typename + iostreams::select< // Disambiguation for Tru64 + mpl::and_< + is_convertible, + is_convertible + >, + BOOST_IOSTREAMS_BASIC_IOSTREAM(Ch, Tr), + is_convertible, + BOOST_IOSTREAMS_BASIC_ISTREAM(Ch, Tr), + else_, + BOOST_IOSTREAMS_BASIC_OSTREAM(Ch, Tr) + >::type stream_type; + typedef typename + iostreams::select< // Dismbiguation required for Tru64. + mpl::and_< + is_convertible, + is_convertible + >, + iostream_tag, + is_convertible, + istream_tag, + else_, + ostream_tag + >::type stream_tag; +}; + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(push) +// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ +# pragma warning(disable: 4250) +#endif + +template +class filtering_stream_base + : public access_control< + boost::iostreams::detail::chain_client, + Access + >, + public filtering_stream_traits< + typename Chain::mode, + typename Chain::char_type, + typename Chain::traits_type + >::stream_type +{ +public: + typedef Chain chain_type; + typedef access_control< + boost::iostreams::detail::chain_client, + Access + > client_type; +protected: + typedef typename + filtering_stream_traits< + typename Chain::mode, + typename Chain::char_type, + typename Chain::traits_type + >::stream_type stream_type; + filtering_stream_base() : stream_type(0) { this->set_chain(&chain_); } +private: + void notify() { this->rdbuf(chain_.empty() ? 0 : &chain_.front()); } + Chain chain_; +}; + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(pop) +#endif + +} // End namespace detail. + +// +// Macro: BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_) +// Description: Defines a template derived from std::basic_streambuf which uses +// a chain to perform i/o. The template has the following parameters: +// Mode - the i/o mode. +// Ch - The character type. +// Tr - The character traits type. +// Alloc - The allocator type. +// Access - Indicates accessibility of the chain interface; must be either +// public_ or protected_; defaults to public_. +// Macro parameters: +// name_ - The name of the template to be defined. +// chain_type_ - The name of the chain template. +// default_char_ - The default value for the char template parameter. +// +#define BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(name_, chain_type_, default_char_) \ + template< typename Mode, \ + typename Ch = default_char_, \ + typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ + typename Alloc = std::allocator, \ + typename Access = public_ > \ + class name_ \ + : public boost::iostreams::detail::filtering_stream_base< \ + chain_type_, Access \ + > \ + { \ + public: \ + typedef Ch char_type; \ + struct category \ + : Mode, \ + closable_tag, \ + detail::filtering_stream_traits::stream_tag \ + { }; \ + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ + typedef Mode mode; \ + typedef chain_type_ chain_type; \ + name_() { } \ + BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \ + ~name_() { \ + if (this->is_complete()) \ + this->rdbuf()->BOOST_IOSTREAMS_PUBSYNC(); \ + } \ + private: \ + typedef access_control< \ + boost::iostreams::detail::chain_client< \ + chain_type_ \ + >, \ + Access \ + > client_type; \ + template \ + void push_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) \ + { client_type::push(t BOOST_IOSTREAMS_PUSH_ARGS()); } \ + }; \ + /**/ + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(push) +// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ +# pragma warning(disable: 4250) +#endif + +BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(filtering_stream, boost::iostreams::chain, char) +BOOST_IOSTREAMS_DEFINE_FILTER_STREAM(wfiltering_stream, boost::iostreams::chain, wchar_t) + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(pop) +#endif + +typedef filtering_stream filtering_istream; +typedef filtering_stream filtering_ostream; +typedef wfiltering_stream filtering_wistream; +typedef wfiltering_stream filtering_wostream; + +//----------------------------------------------------------------------------// + +} } // End namespace iostreams, boost + +#include // MSVC + +#endif // #ifndef BOOST_IOSTREAMS_FILTER_STREAM_HPP_INCLUDED diff --git a/boost/iostreams/filtering_streambuf.hpp b/boost/iostreams/filtering_streambuf.hpp new file mode 100644 index 0000000..affe4a7 --- /dev/null +++ b/boost/iostreams/filtering_streambuf.hpp @@ -0,0 +1,70 @@ +// (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 BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED +#define BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // allocator. +#include +#include +#include +#include +#include // pubsync. +#include +#include + +namespace boost { namespace iostreams { + +// +// Macro: BOOST_IOSTREAMS_DEFINE_FILTERBUF(name_, chain_type_, default_char_) +// Description: Defines a template derived from std::basic_streambuf which uses +// a chain to perform i/o. The template has the following parameters: +// Ch - The character type. +// Tr - The character traits type. +// Alloc - The allocator type. +// Access - Indicates accessibility of the chain interface; must be either +// public_ or protected_; defaults to public_. +// +#define BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(name_, chain_type_, default_char_) \ + template< typename Mode, \ + typename Ch = default_char_, \ + typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch), \ + typename Alloc = std::allocator, \ + typename Access = public_ > \ + class name_ : public boost::iostreams::detail::chainbuf< \ + chain_type_, Mode, Access \ + > \ + { \ + public: \ + typedef Ch char_type; \ + struct category \ + : Mode, closable_tag, streambuf_tag \ + { }; \ + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ + typedef Mode mode; \ + typedef chain_type_ chain_type; \ + name_() { } \ + BOOST_IOSTREAMS_DEFINE_PUSH_CONSTRUCTOR(name_, mode, Ch, push_impl) \ + ~name_() { if (this->is_complete()) this->BOOST_IOSTREAMS_PUBSYNC(); } \ + }; \ + /**/ +BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_streambuf, boost::iostreams::chain, char) +BOOST_IOSTREAMS_DEFINE_FILTER_STREAMBUF(filtering_wstreambuf, boost::iostreams::chain, wchar_t) + +typedef filtering_streambuf filtering_istreambuf; +typedef filtering_streambuf filtering_ostreambuf; +typedef filtering_wstreambuf filtering_wistreambuf; +typedef filtering_wstreambuf filtering_wostreambuf; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_FILTERING_STREAMBUF_HPP_INCLUDED diff --git a/boost/iostreams/flush.hpp b/boost/iostreams/flush.hpp new file mode 100644 index 0000000..5212a44 --- /dev/null +++ b/boost/iostreams/flush.hpp @@ -0,0 +1,125 @@ +// (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 BOOST_IOSTREAMS_FLUSH_HPP_INCLUDED +#define BOOST_IOSTREAMS_FLUSH_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct flush_device_impl; + +template +struct flush_filter_impl; + +} // End namespace detail. + +template +bool flush(T& t) +{ return detail::flush_device_impl::flush(detail::unwrap(t)); } + +template +bool flush(T& t, Sink& snk) +{ return detail::flush_filter_impl::flush(detail::unwrap(t), snk); } + +namespace detail { + +//------------------Definition of flush_device_impl---------------------------// + +template +struct flush_device_impl + : mpl::if_< + is_custom, + operations, + flush_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, ostream_tag, streambuf_tag, flushable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) + { return t.rdbuf()->BOOST_IOSTREAMS_PUBSYNC() == 0; } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) + { return t.BOOST_IOSTREAMS_PUBSYNC() == 0; } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T& t) { return t.flush(); } +}; + +template<> +struct flush_device_impl { + template + static bool flush(T&) { return true; } +}; + +//------------------Definition of flush_filter_impl---------------------------// + +template +struct flush_filter_impl + : mpl::if_< + is_custom, + operations, + flush_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, flushable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct flush_filter_impl { + template + static bool flush(T& t, Sink& snk) { return t.flush(snk); } +}; + +template<> +struct flush_filter_impl { + template + static bool flush(T&, Sink&) { return false; } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_FLUSH_HPP_INCLUDED diff --git a/boost/iostreams/get.hpp b/boost/iostreams/get.hpp new file mode 100644 index 0000000..12d530f --- /dev/null +++ b/boost/iostreams/get.hpp @@ -0,0 +1,17 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_GET_HPP_INCLUDED +#define BOOST_IOSTREAMS_GET_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_GET_HPP_INCLUDED diff --git a/boost/iostreams/imbue.hpp b/boost/iostreams/imbue.hpp new file mode 100644 index 0000000..48d2e18 --- /dev/null +++ b/boost/iostreams/imbue.hpp @@ -0,0 +1,82 @@ +// (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 BOOST_IOSTREAMS_IMBUE_HPP_INCLUDED +#define BOOST_IOSTREAMS_IMBUE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +// Implementation templates for simulated tag dispatch. +template +struct imbue_impl; + +} // End namespace detail. + +template +void imbue(T& t, const Locale& loc) +{ detail::imbue_impl::imbue(detail::unwrap(t), loc); } + +namespace detail { + +//------------------Definition of imbue_impl----------------------------------// + +template +struct imbue_impl + : mpl::if_< + is_custom, + operations, + imbue_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, streambuf_tag, localizable_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct imbue_impl { + template + static void imbue(T&, const Locale&) { } +}; + +template<> +struct imbue_impl { + template + static void imbue(T& t, const Locale& loc) { t.pubimbue(loc); } +}; + +template<> +struct imbue_impl { + template + static void imbue(T& t, const Locale& loc) { t.imbue(loc); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_IMBUE_HPP_INCLUDED diff --git a/boost/iostreams/input_sequence.hpp b/boost/iostreams/input_sequence.hpp new file mode 100644 index 0000000..e504c8e --- /dev/null +++ b/boost/iostreams/input_sequence.hpp @@ -0,0 +1,72 @@ +// (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 BOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED +#define BOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // pair. +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include // is_custom +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct input_sequence_impl; + +} // End namespace detail. + +template +inline std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* +> +input_sequence(T& t) +{ return detail::input_sequence_impl::input_sequence(t); } + +namespace detail { + +//------------------Definition of direct_impl-------------------------------// + +template +struct input_sequence_impl + : mpl::if_< + detail::is_custom, + operations, + input_sequence_impl + >::type + { }; + +template<> +struct input_sequence_impl { + template + static std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* + > + input_sequence(U& u) { return u.input_sequence(); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_INPUT_SEQUENCE_HPP_INCLUDED diff --git a/boost/iostreams/invert.hpp b/boost/iostreams/invert.hpp new file mode 100644 index 0000000..d4a17bf --- /dev/null +++ b/boost/iostreams/invert.hpp @@ -0,0 +1,167 @@ +// (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 BOOST_IOSTREAMS_INVERT_HPP_INCLUDED +#define BOOST_IOSTREAMS_INVERT_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // copy, min. +#include +#include // BOOST_DEDUCED_TYPENAME. +#include // default_filter_buffer_size. +#include +#include +#include +#include +#include +#include +#include +#include // clear_flags, call_reset +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { + +// +// Template name: inverse. +// Template parameters: +// Filter - A model of InputFilter or OutputFilter. +// Description: Generates an InputFilter from an OutputFilter or +// vice versa. +// +template +class inverse { +private: + BOOST_STATIC_ASSERT(is_filter::value); + typedef typename category_of::type base_category; + typedef reference_wrapper filter_ref; +public: + typedef typename char_type_of::type char_type; + typedef typename int_type_of::type int_type; + typedef char_traits traits_type; + typedef typename + mpl::if_< + is_convertible< + base_category, + input + >, + output, + input + >::type mode; + struct category + : mode, + filter_tag, + multichar_tag, + closable_tag + { }; + explicit inverse( const Filter& filter, + std::streamsize buffer_size = + default_filter_buffer_size) + : pimpl_(new impl(filter, buffer_size)) + { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + typedef detail::counted_array_sink array_sink; + typedef composite filtered_array_sink; + + BOOST_ASSERT((flags() & f_write) == 0); + if (flags() == 0) { + flags() = f_read; + buf().set(0, 0); + } + + filtered_array_sink snk(filter(), array_sink(s, n)); + int_type status; + for ( status = traits_type::good(); + snk.second().count() < n && status == traits_type::good(); ) + { + status = buf().fill(src); + buf().flush(snk); + } + return snk.second().count() == 0 && + status == traits_type::eof() + ? + -1 + : + snk.second().count(); + } + + template + std::streamsize write(Sink& dest, const char_type* s, std::streamsize n) + { + typedef detail::counted_array_source array_source; + typedef composite filtered_array_source; + + BOOST_ASSERT((flags() & f_read) == 0); + if (flags() == 0) { + flags() = f_write; + buf().set(0, 0); + } + + filtered_array_source src(filter(), array_source(s, n)); + for (bool good = true; src.second().count() < n && good; ) { + buf().fill(src); + good = buf().flush(dest); + } + return src.second().count(); + } + + template + void close(Device& dev) + { + detail::execute_all( + detail::flush_buffer(buf(), dev, (flags() & f_write) != 0), + detail::call_close_all(pimpl_->filter_, dev), + detail::clear_flags(flags()) + ); + } +private: + filter_ref filter() { return boost::ref(pimpl_->filter_); } + detail::buffer& buf() { return pimpl_->buf_; } + int& flags() { return pimpl_->flags_; } + + enum flags_ { + f_read = 1, f_write = 2 + }; + + struct impl { + impl(const Filter& filter, std::streamsize n) + : filter_(filter), buf_(n), flags_(0) + { buf_.set(0, 0); } + Filter filter_; + detail::buffer buf_; + int flags_; + }; + shared_ptr pimpl_; +}; + +// +// Template name: invert. +// Template parameters: +// Filter - A model of InputFilter or OutputFilter. +// Description: Returns an instance of an appropriate specialization of inverse. +// +template +inverse invert(const Filter& f) { return inverse(f); } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_INVERT_HPP_INCLUDED diff --git a/boost/iostreams/operations.hpp b/boost/iostreams/operations.hpp new file mode 100644 index 0000000..28bd773 --- /dev/null +++ b/boost/iostreams/operations.hpp @@ -0,0 +1,26 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#endif // #ifndef BOOST_IOSTREAMS_OPERATIONS_HPP_INCLUDED diff --git a/boost/iostreams/operations_fwd.hpp b/boost/iostreams/operations_fwd.hpp new file mode 100644 index 0000000..ae68d70 --- /dev/null +++ b/boost/iostreams/operations_fwd.hpp @@ -0,0 +1,41 @@ +// (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 BOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include + +namespace boost { namespace iostreams { + +template +struct operations; + +namespace detail { + +struct custom_tag { }; + +template +struct is_custom + : mpl::not_< + is_base_and_derived< custom_tag, operations > + > + { }; + +} // End namespace detail. + +template +struct operations : detail::custom_tag { }; + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_OPERATIONS_FWD_HPP_INCLUDED //--------------// diff --git a/boost/iostreams/optimal_buffer_size.hpp b/boost/iostreams/optimal_buffer_size.hpp new file mode 100644 index 0000000..13894fa --- /dev/null +++ b/boost/iostreams/optimal_buffer_size.hpp @@ -0,0 +1,87 @@ +// (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 BOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED +#define BOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include // constants. +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct optimal_buffer_size_impl; + +} // End namespace detail. + +template +std::streamsize optimal_buffer_size(const T& t) +{ + typedef detail::optimal_buffer_size_impl impl; + return impl::optimal_buffer_size(detail::unwrap(t)); +} + +namespace detail { + +//------------------Definition of optimal_buffer_size_impl--------------------// + +template +struct optimal_buffer_size_impl + : mpl::if_< + is_custom, + operations, + optimal_buffer_size_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, optimally_buffered_tag, device_tag, filter_tag + >::type + > + >::type + { }; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T& t) + { return t.optimal_buffer_size(); } +}; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T&) + { return default_device_buffer_size; } +}; + +template<> +struct optimal_buffer_size_impl { + template + static std::streamsize optimal_buffer_size(const T&) + { return default_filter_buffer_size; } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_OPTIMAL_BUFFER_SIZE_HPP_INCLUDED diff --git a/boost/iostreams/output_sequence.hpp b/boost/iostreams/output_sequence.hpp new file mode 100644 index 0000000..5b42bf4 --- /dev/null +++ b/boost/iostreams/output_sequence.hpp @@ -0,0 +1,72 @@ +// (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 BOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED +#define BOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // pair. +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include // is_custom +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct output_sequence_impl; + +} // End namespace detail. + +template +inline std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* +> +output_sequence(T& t) +{ return detail::output_sequence_impl::output_sequence(t); } + +namespace detail { + +//------------------Definition of output_sequence_impl------------------------// + +template +struct output_sequence_impl + : mpl::if_< + detail::is_custom, + operations, + output_sequence_impl + >::type + { }; + +template<> +struct output_sequence_impl { + template + static std::pair< + BOOST_DEDUCED_TYPENAME char_type_of::type*, + BOOST_DEDUCED_TYPENAME char_type_of::type* + > + output_sequence(U& u) { return u.output_sequence(); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_OUTPUT_SEQUENCE_HPP_INCLUDED diff --git a/boost/iostreams/pipeline.hpp b/boost/iostreams/pipeline.hpp new file mode 100644 index 0000000..ad792ab --- /dev/null +++ b/boost/iostreams/pipeline.hpp @@ -0,0 +1,114 @@ +// (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 BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED +#define BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // BOOST_MSVC. +#include +#include +#include +#include +#include +#include +#include + +#define BOOST_IOSTREAMS_PIPABLE(filter, arity) \ + template< BOOST_PP_ENUM_PARAMS(arity, typename T) \ + BOOST_PP_COMMA_IF(arity) typename Component> \ + ::boost::iostreams::pipeline< \ + ::boost::iostreams::detail::pipeline_segment< \ + filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ + >, \ + Component \ + > operator|( const filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T)& f, \ + const Component& c ) \ + { \ + typedef ::boost::iostreams::detail::pipeline_segment< \ + filter BOOST_IOSTREAMS_TEMPLATE_ARGS(arity, T) \ + > segment; \ + return ::boost::iostreams::pipeline \ + (segment(f), c); \ + } \ + /**/ + +namespace boost { namespace iostreams { + +template +struct pipeline; + +namespace detail { + +#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) + template + struct is_pipeline : mpl::false_ { }; + + template + struct is_pipeline< pipeline > : mpl::true_ { }; +#endif + +template +class pipeline_segment +{ +public: + pipeline_segment(const Component& component) + : component_(component) + { } + template + void for_each(Fn fn) const { fn(component_); } + template + void push(Chain& chn) const { chn.push(component_); } +private: + pipeline_segment operator=(const pipeline_segment&); + const Component& component_; +}; + +} // End namespace detail. + +//------------------Definition of Pipeline------------------------------------// + +template +struct pipeline : Pipeline { + typedef Pipeline pipeline_type; + typedef Component component_type; + pipeline(const Pipeline& p, const Component& component) + : Pipeline(p), component_(component) + { } + template + void for_each(Fn fn) const + { + Pipeline::for_each(fn); + fn(component_); + } + template + void push(Chain& chn) const + { + Pipeline::push(chn); + chn.push(component_); + } + const Pipeline& tail() const { return *this; } + const Component& head() const { return component_; } +private: + pipeline operator=(const pipeline&); + const Component& component_; +}; + +template +pipeline, Component> +operator|(const pipeline& p, const Component& cmp) +{ + BOOST_STATIC_ASSERT(is_filter::value); + return pipeline, Component>(p, cmp); +} + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_PIPABLE_HPP_INCLUDED diff --git a/boost/iostreams/positioning.hpp b/boost/iostreams/positioning.hpp new file mode 100644 index 0000000..12f2afc --- /dev/null +++ b/boost/iostreams/positioning.hpp @@ -0,0 +1,117 @@ +// (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. + +// Thanks to Gareth Sylvester-Bradley for the Dinkumware versions of the +// positioning functions. + +#ifndef BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED +#define BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include // mbstate_t. +#include +#include // streamoff, streampos. + +// Must come last. +#include + +#ifdef BOOST_NO_STDC_NAMESPACE +namespace std { using ::fpos_t; } +#endif + +namespace boost { namespace iostreams { + +//------------------Definition of stream_offset-------------------------------// + +typedef boost::intmax_t stream_offset; + +//------------------Definition of stream_offset_to_streamoff------------------// + +inline std::streamoff stream_offset_to_streamoff(stream_offset off) +{ return static_cast(off); } + +//------------------Definition of offset_to_position--------------------------// + +# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline std::streampos offset_to_position(stream_offset off) { return off; } + +# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline std::streampos offset_to_position(stream_offset off) +{ return std::streampos(std::mbstate_t(), off); } + +# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +//------------------Definition of position_to_offset--------------------------// + +// Hande custom pos_type's +template +inline stream_offset position_to_offset(PosType pos) +{ return std::streamoff(pos); } + +# ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +inline stream_offset position_to_offset(std::streampos pos) { return pos; } + +# else // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +// In the Dinkumware standard library, a std::streampos consists of two stream +// offsets -- _Fpos, of type std::fpos_t, and _Myoff, of type std::streamoff -- +// together with a conversion state. A std::streampos is converted to a +// boost::iostreams::stream_offset by extracting the two stream offsets and +// summing them. The value of _Fpos can be extracted using the implementation- +// defined member functions seekpos() or get_fpos_t(), depending on the +// Dinkumware version. The value of _Myoff cannot be extracted directly, but can +// be calculated as the difference between the result of converting the +// std::fpos to a std::streamoff and the result of converting the member _Fpos +// to a long. The latter operation is accomplished with the macro BOOST_IOSTREAMS_FPOSOFF, +// which works correctly on platforms where std::fpos_t is an integral type and +// platforms where it is a struct + +// Converts a std::fpos_t to a stream_offset +inline stream_offset fpos_t_to_offset(std::fpos_t pos) +{ +# if defined(_POSIX_) || (_INTEGRAL_MAX_BITS >= 64) || defined(__IBMCPP__) + return pos; +# else + return BOOST_IOSTREAMS_FPOSOFF(pos); +# endif +} + +// Extracts the member _Fpos from a std::fpos +inline std::fpos_t streampos_to_fpos_t(std::streampos pos) +{ +# if defined (_CPPLIB_VER) || defined(__IBMCPP__) + return pos.seekpos(); +# else + return pos.get_fpos_t(); +# endif +} + +inline stream_offset position_to_offset(std::streampos pos) +{ + return fpos_t_to_offset(streampos_to_fpos_t(pos)) + + static_cast( + static_cast(pos) - + BOOST_IOSTREAMS_FPOSOFF(streampos_to_fpos_t(pos)) + ); +} + +# endif // # ifndef BOOST_IOSTREAMS_HAS_DINKUMWARE_FPOS + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_POSITIONING_HPP_INCLUDED diff --git a/boost/iostreams/put.hpp b/boost/iostreams/put.hpp new file mode 100644 index 0000000..a3fe33f --- /dev/null +++ b/boost/iostreams/put.hpp @@ -0,0 +1,17 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_PUT_HPP_INCLUDED +#define BOOST_IOSTREAMS_PUT_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_PUT_HPP_INCLUDED diff --git a/boost/iostreams/putback.hpp b/boost/iostreams/putback.hpp new file mode 100644 index 0000000..a4969f6 --- /dev/null +++ b/boost/iostreams/putback.hpp @@ -0,0 +1,17 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED +#define BOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include + +#endif // #ifndef BOOST_IOSTREAMS_PUTBACK_HPP_INCLUDED diff --git a/boost/iostreams/read.hpp b/boost/iostreams/read.hpp new file mode 100644 index 0000000..a8652c5 --- /dev/null +++ b/boost/iostreams/read.hpp @@ -0,0 +1,241 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_READ_HPP_INCLUDED +#define BOOST_IOSTREAMS_READ_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // streamsize. +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct read_device_impl; + +template +struct read_filter_impl; + +} // End namespace detail. + +template +typename int_type_of::type get(T& t) +{ return detail::read_device_impl::get(detail::unwrap(t)); } + +template +inline std::streamsize +read(T& t, typename char_type_of::type* s, std::streamsize n) +{ return detail::read_device_impl::read(detail::unwrap(t), s, n); } + +template +std::streamsize +read(T& t, Source& src, typename char_type_of::type* s, std::streamsize n) +{ return detail::read_filter_impl::read(detail::unwrap(t), src, s, n); } + +template +bool putback(T& t, typename char_type_of::type c) +{ return detail::read_device_impl::putback(detail::unwrap(t), c); } + +//----------------------------------------------------------------------------// + +namespace detail { + +// Helper function for adding -1 as EOF indicator. +inline std::streamsize check_eof(std::streamsize n) { return n != 0 ? n : -1; } + +// Helper templates for reading from streambufs. +template +struct true_eof_impl; + +template<> +struct true_eof_impl { + template + static bool true_eof(T& t) { return t.true_eof(); } +}; + +template<> +struct true_eof_impl { + template + static bool true_eof(T&) { return true; } +}; + +template +inline bool true_eof(T& t) +{ + const bool linked = is_linked::value; + return true_eof_impl::true_eof(t); +} + +//------------------Definition of read_device_impl----------------------------// + +template +struct read_device_impl + : mpl::if_< + detail::is_custom, + operations, + read_device_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, istream_tag, streambuf_tag, input + >::type + > + >::type + { }; + +template<> +struct read_device_impl { + template + static typename int_type_of::type get(T& t) + { return t.get(); } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return check_eof(t.rdbuf()->sgetn(s, n)); } + + template + static bool putback(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->sputbackc(c), + traits_type::eof() ); + } +}; + +template<> +struct read_device_impl { + template + static typename int_type_of::type + get(T& t) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + typename int_type_of::type c; + return !traits_type::is_eof(c = t.sbumpc()) || + detail::true_eof(t) + ? + c : traits_type::would_block(); + } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { + std::streamsize amt; + return (amt = t.sgetn(s, n)) != 0 ? + amt : + detail::true_eof(t) ? + -1 : + 0; + } + + template + static bool putback(T& t, typename char_type_of::type c) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + return !traits_type::is_eof(t.sputbackc(c)); + } +}; + +template<> +struct read_device_impl { + template + static typename int_type_of::type + get(T& t) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + char_type c; + std::streamsize amt; + return (amt = t.read(&c, 1)) == 1 ? + traits_type::to_int_type(c) : + amt == -1 ? + traits_type::eof() : + traits_type::would_block(); + } + + template + static std::streamsize + read(T& t, typename char_type_of::type* s, std::streamsize n) + { return t.read(s, n); } + + template + static bool putback(T& t, typename char_type_of::type c) + { // T must be Peekable. + return t.putback(c); + } +}; + +//------------------Definition of read_filter_impl----------------------------// + +template +struct read_filter_impl + : mpl::if_< + detail::is_custom, + operations, + read_filter_impl< + BOOST_DEDUCED_TYPENAME + detail::dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct read_filter_impl { + template + static std::streamsize read + (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) + { return t.read(src, s, n); } +}; + +template<> +struct read_filter_impl { + template + static std::streamsize read + (T& t, Source& src, typename char_type_of::type* s, std::streamsize n) + { // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + for (std::streamsize off = 0; off < n; ++off) { + typename traits_type::int_type c = t.get(src); + if (traits_type::is_eof(c)) + return check_eof(off); + if (traits_type::would_block(c)) + return off; + s[off] = traits_type::to_char_type(c); + } + return n; + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_READ_HPP_INCLUDED diff --git a/boost/iostreams/restrict.hpp b/boost/iostreams/restrict.hpp new file mode 100644 index 0000000..e17eb8c --- /dev/null +++ b/boost/iostreams/restrict.hpp @@ -0,0 +1,26 @@ +/* + * 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. + * + * File: boost/iostreams/detail/restrict.hpp + * Date: Sun Jan 06 12:57:30 MST 2008 + * Copyright: 2008 CodeRage, LLC + 2004-2007 Jonathan Turkanis + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the class template boost::iostreams::restriction and the + * overloaded function template boost::iostreams::restrict + */ + +#ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED +#define BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED + +#include +#define BOOST_IOSTREAMS_RESTRICT restrict +#include +#undef BOOST_IOSTREAMS_RESTRICT + +#endif // #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED diff --git a/boost/iostreams/seek.hpp b/boost/iostreams/seek.hpp new file mode 100644 index 0000000..148c90b --- /dev/null +++ b/boost/iostreams/seek.hpp @@ -0,0 +1,180 @@ +// (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 BOOST_IOSTREAMS_SEEK_HPP_INCLUDED +#define BOOST_IOSTREAMS_SEEK_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include // streamsize, seekdir, openmode. +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct seek_device_impl; + +template +struct seek_filter_impl; + +} // End namespace detail. + +template +inline std::streampos +seek( T& t, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + return seek_device_impl::seek(detail::unwrap(t), off, way, which); +} + +template +inline std::streampos +seek( T& t, Device& dev, stream_offset off, BOOST_IOS::seekdir way, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + using namespace detail; + return seek_filter_impl::seek(detail::unwrap(t), dev, off, way, which); +} + +namespace detail { + +//------------------Definition of seek_device_impl----------------------------// + +template +struct seek_device_impl + : mpl::if_< + is_custom, + operations, + seek_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, iostream_tag, istream_tag, ostream_tag, + streambuf_tag, two_head, any_tag + >::type + > + >::type + { }; + +struct seek_impl_basic_ios { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + if ( way == BOOST_IOS::beg && + ( off < integer_traits::const_min || + off > integer_traits::const_max ) ) + { + return t.rdbuf()->pubseekpos(offset_to_position(off)); + } else { + return t.rdbuf()->pubseekoff(off, way, which); + } + } +}; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl : seek_impl_basic_ios { }; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { + if ( way == BOOST_IOS::beg && + ( off < integer_traits::const_min || + off > integer_traits::const_max ) ) + { + return t.BOOST_IOSTREAMS_PUBSEEKPOS(offset_to_position(off)); + } else { + return t.BOOST_IOSTREAMS_PUBSEEKOFF(off, way, which); + } + } +}; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return t.seek(off, way, which); } +}; + +template<> +struct seek_device_impl { + template + static std::streampos seek( T& t, stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode ) + { return t.seek(off, way); } +}; + +//------------------Definition of seek_filter_impl----------------------------// + +template +struct seek_filter_impl + : mpl::if_< + is_custom, + operations, + seek_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch::type + > + >::type + { }; + +template<> +struct seek_filter_impl { + template + static std::streampos seek( T& t, Device& d, + stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode which ) + { return t.seek(d, off, way, which); } +}; + +template<> +struct seek_filter_impl { + template + static std::streampos seek( T& t, Device& d, + stream_offset off, + BOOST_IOS::seekdir way, + BOOST_IOS::openmode ) + { return t.seek(d, off, way); } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_SEEK_HPP_INCLUDED diff --git a/boost/iostreams/skip.hpp b/boost/iostreams/skip.hpp new file mode 100644 index 0000000..eb097dd --- /dev/null +++ b/boost/iostreams/skip.hpp @@ -0,0 +1,112 @@ +// (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. + +// To do: handle bidirection streams and output-seekable components. + +#ifndef BOOST_IOSTREAMS_SKIP_HPP_INCLUDED +#define BOOST_IOSTREAMS_SKIP_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // failure. +#include +#include +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +void skip(Device& dev, stream_offset off, mpl::true_) +{ iostreams::seek(dev, off, BOOST_IOS::cur); } + +template +void skip(Device& dev, stream_offset off, mpl::false_) +{ // gcc 2.95 needs namespace qualification for char_traits. + typedef typename char_type_of::type char_type; + typedef iostreams::char_traits traits_type; + for (stream_offset z = 0; z < off; ) { + typename traits_type::int_type c; + if (traits_type::is_eof(c = iostreams::get(dev))) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset")); + if (!traits_type::would_block(c)) + ++z; + } +} + +template +void skip( Filter& flt, Device& dev, stream_offset off, + BOOST_IOS::openmode which, mpl::true_ ) +{ boost::iostreams::seek(flt, dev, off, BOOST_IOS::cur, which); } + +template +void skip( Filter& flt, Device& dev, stream_offset off, + BOOST_IOS::openmode, mpl::false_ ) +{ + typedef typename char_type_of::type char_type; + char_type c; + for (stream_offset z = 0; z < off; ) { + std::streamsize amt; + if ((amt = iostreams::read(flt, dev, &c, 1)) == -1) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad skip offset")); + if (amt == 1) + ++z; + } +} + +} // End namespace detail. + +template +void skip(Device& dev, stream_offset off) +{ + typedef typename mode_of::type mode; + typedef mpl::or_< + is_convertible, + is_convertible + > can_seek; + BOOST_STATIC_ASSERT( + (can_seek::value || is_convertible::value) + ); + detail::skip(dev, off, can_seek()); +} + +template +void skip( Filter& flt, Device& dev, stream_offset off, + BOOST_IOS::openmode which = BOOST_IOS::in | BOOST_IOS::out ) +{ + typedef typename mode_of::type filter_mode; + typedef typename mode_of::type device_mode; + typedef mpl::or_< + mpl::and_< + is_convertible, + is_convertible + >, + mpl::and_< + is_convertible, + is_convertible + > + > can_seek; + BOOST_STATIC_ASSERT( + ( can_seek::value || + (is_convertible::value && + is_convertible::value) ) + ); + detail::skip(flt, dev, off, which, can_seek()); +} + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_SKIP_HPP_INCLUDED //------------------------// diff --git a/boost/iostreams/slice.hpp b/boost/iostreams/slice.hpp new file mode 100644 index 0000000..820a316 --- /dev/null +++ b/boost/iostreams/slice.hpp @@ -0,0 +1,28 @@ +/* + * 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. + * + * File: boost/iostreams/detail/restrict.hpp + * Date: Sun Jan 06 12:57:30 MST 2008 + * Copyright: 2008 CodeRage, LLC + 2004-2007 Jonathan Turkanis + * Author: Jonathan Turkanis + * Contact: turkanis at coderage dot com + * + * Defines the class template boost::iostreams::restriction and the + * overloaded function template boost::iostreams::slice. + * + * This header is provided for platforms on which "restrict" is a keyword. + */ + +#ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED +#define BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED + +#include +#define BOOST_IOSTREAMS_RESTRICT slice +#include +#undef BOOST_IOSTREAMS_RESTRICT + +#endif // #ifndef BOOST_IOSTREAMS_RESTRICT_HPP_INCLUDED diff --git a/boost/iostreams/stream.hpp b/boost/iostreams/stream.hpp new file mode 100644 index 0000000..c581837 --- /dev/null +++ b/boost/iostreams/stream.hpp @@ -0,0 +1,171 @@ +// (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 BOOST_IOSTREAMS_STREAM_HPP_INCLUDED +#define BOOST_IOSTREAMS_STREAM_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include +#include +#include +#include // standard streams. +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { namespace detail { + +template +struct stream_traits { + typedef typename char_type_of::type char_type; + typedef Tr traits_type; + typedef typename category_of::type mode; + typedef typename + iostreams::select< // Disambiguation required for Tru64. + mpl::and_< + is_convertible, + is_convertible + >, + BOOST_IOSTREAMS_BASIC_IOSTREAM(char_type, traits_type), + is_convertible, + BOOST_IOSTREAMS_BASIC_ISTREAM(char_type, traits_type), + else_, + BOOST_IOSTREAMS_BASIC_OSTREAM(char_type, traits_type) + >::type stream_type; + typedef typename + iostreams::select< // Disambiguation required for Tru64. + mpl::and_< + is_convertible, + is_convertible + >, + iostream_tag, + is_convertible, + istream_tag, + else_, + ostream_tag + >::type stream_tag; +}; + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(push) +// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ +# pragma warning(disable: 4250) +#endif + +// By encapsulating initialization in a base, we can define the macro +// BOOST_IOSTREAMS_DEFINE_FORWARDING_FUNCTIONS to generate constructors +// without base member initializer lists. +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Base = // VC6 Workaround. + BOOST_DEDUCED_TYPENAME + detail::stream_traits::stream_type > +class stream_base + : protected base_from_member< stream_buffer >, + public Base +{ +private: + typedef base_from_member< stream_buffer > pbase_type; + typedef typename stream_traits::stream_type stream_type; +protected: + using pbase_type::member; // Avoid warning about 'this' in initializer list. +public: + stream_base() : pbase_type(), stream_type(&member) { } +}; + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(pop) +#endif + +} } } // End namespaces detail, iostreams, boost. + +#ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# include +#else + +namespace boost { namespace iostreams { + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(push) +// https://connect.microsoft.com/VisualStudio/feedback/details/733720/ +# pragma warning(disable: 4250) +#endif + +// +// Template name: stream. +// Description: A iostream which reads from and writes to an instance of a +// designated device type. +// Template parameters: +// Device - A device type. +// Alloc - The allocator type. +// +template< typename Device, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + > > +struct stream : detail::stream_base { +public: + typedef typename char_type_of::type char_type; + struct category + : mode_of::type, + closable_tag, + detail::stream_traits::stream_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +private: + typedef typename + detail::stream_traits< + Device, Tr + >::stream_type stream_type; +public: + stream() { } + BOOST_IOSTREAMS_FORWARD( stream, open_impl, Device, + BOOST_IOSTREAMS_PUSH_PARAMS, + BOOST_IOSTREAMS_PUSH_ARGS ) + bool is_open() const { return this->member.is_open(); } + void close() { this->member.close(); } + bool auto_close() const { return this->member.auto_close(); } + void set_auto_close(bool close) { this->member.set_auto_close(close); } + bool strict_sync() { return this->member.strict_sync(); } + Device& operator*() { return *this->member; } + Device* operator->() { return &*this->member; } + Device* component() { return this->member.component(); } +private: + void open_impl(const Device& dev BOOST_IOSTREAMS_PUSH_PARAMS()) // For forwarding. + { + this->clear(); + this->member.open(dev BOOST_IOSTREAMS_PUSH_ARGS()); + } +}; + +#if defined(BOOST_MSVC) && (BOOST_MSVC == 1700) +# pragma warning(pop) +#endif + +} } // End namespaces iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION + +#endif // #ifndef BOOST_IOSTREAMS_stream_HPP_INCLUDED diff --git a/boost/iostreams/stream_buffer.hpp b/boost/iostreams/stream_buffer.hpp new file mode 100644 index 0000000..dbcb786 --- /dev/null +++ b/boost/iostreams/stream_buffer.hpp @@ -0,0 +1,116 @@ +// (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 BOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED +#define BOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // allocator. +#include // BOOST_DEDUCED_TYPENAME. +#include +#include +#include +#include // failure, streamsize. +#include +#include +#include +#include +#include +#include + +// Must come last. +#include // MSVC. + +namespace boost { namespace iostreams { namespace detail { + +template +struct stream_buffer_traits { + typedef typename + mpl::if_< + is_convertible< + BOOST_DEDUCED_TYPENAME category_of::type, + direct_tag + >, + direct_streambuf, + indirect_streambuf + >::type type; +}; + +} } } // End namespaces detail, iostreams, boost + +#ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION +# include +#else + +namespace boost { namespace iostreams { + +template< typename T, + typename Tr = + BOOST_IOSTREAMS_CHAR_TRAITS( + BOOST_DEDUCED_TYPENAME char_type_of::type + ), + typename Alloc = + std::allocator< + BOOST_DEDUCED_TYPENAME char_type_of::type + >, + typename Mode = BOOST_DEDUCED_TYPENAME mode_of::type > +class stream_buffer + : public detail::stream_buffer_traits::type +{ +private: + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, Mode + >::value + )); + typedef typename + detail::stream_buffer_traits< + T, Tr, Alloc, Mode + >::type base_type; +public: + typedef typename char_type_of::type char_type; + struct category + : Mode, + closable_tag, + streambuf_tag + { }; + BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) +public: + stream_buffer() { } + ~stream_buffer() + { + try { + if (this->is_open() && this->auto_close()) + this->close(); + } catch (...) { } + } + BOOST_IOSTREAMS_FORWARD( stream_buffer, open_impl, T, + BOOST_IOSTREAMS_PUSH_PARAMS, + BOOST_IOSTREAMS_PUSH_ARGS ) + T& operator*() { return *this->component(); } + T* operator->() { return this->component(); } +private: + void open_impl(const T& t BOOST_IOSTREAMS_PUSH_PARAMS()) + { // Used for forwarding. + if (this->is_open()) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("already open") + ); + base_type::open(t BOOST_IOSTREAMS_PUSH_ARGS()); + } +}; + +} } // End namespaces iostreams, boost. + +#endif // #ifdef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION + +#include // MSVC. + +#endif // #ifndef BOOST_IOSTREAMS_STREAM_BUFFER_HPP_INCLUDED diff --git a/boost/iostreams/tee.hpp b/boost/iostreams/tee.hpp new file mode 100644 index 0000000..6df85e9 --- /dev/null +++ b/boost/iostreams/tee.hpp @@ -0,0 +1,232 @@ +// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +// (C) Copyright 2005-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 BOOST_IOSTREAMS_TEE_HPP_INCLUDED +#define BOOST_IOSTREAMS_TEE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include +#include // BOOST_DEDUCE_TYPENAME. +#include +#include +#include +#include +#include +#include // call_close_all +#include +#include +#include +#include +#include +#include + +namespace boost { namespace iostreams { + +// +// Template name: tee_filter. +// Template parameters: +// Device - A blocking Sink. +// +template +class tee_filter : public detail::filter_adapter { +public: + typedef typename detail::param_type::type param_type; + typedef typename char_type_of::type char_type; + struct category + : dual_use_filter_tag, + multichar_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + + BOOST_STATIC_ASSERT(is_device::value); + BOOST_STATIC_ASSERT(( + is_convertible< // Using mode_of causes failures on VC6-7.0. + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output + >::value + )); + + explicit tee_filter(param_type dev) + : detail::filter_adapter(dev) + { } + + template + std::streamsize read(Source& src, char_type* s, std::streamsize n) + { + std::streamsize result = iostreams::read(src, s, n); + if (result != -1) { + std::streamsize result2 = iostreams::write(this->component(), s, result); + (void) result2; // Suppress 'unused variable' warning. + BOOST_ASSERT(result == result2); + } + return result; + } + + template + std::streamsize write(Sink& snk, const char_type* s, std::streamsize n) + { + std::streamsize result = iostreams::write(snk, s, n); + std::streamsize result2 = iostreams::write(this->component(), s, result); + (void) result2; // Suppress 'unused variable' warning. + BOOST_ASSERT(result == result2); + return result; + } + + template + void close(Next&, BOOST_IOS::openmode) + { + detail::close_all(this->component()); + } + + template + bool flush(Sink& snk) + { + bool r1 = iostreams::flush(snk); + bool r2 = iostreams::flush(this->component()); + return r1 && r2; + } +}; +BOOST_IOSTREAMS_PIPABLE(tee_filter, 1) + +// +// Template name: tee_device. +// Template parameters: +// Device - A blocking Device. +// Sink - A blocking Sink. +// +template +class tee_device { +public: + typedef typename detail::param_type::type device_param; + typedef typename detail::param_type::type sink_param; + typedef typename detail::value_type::type device_value; + typedef typename detail::value_type::type sink_value; + typedef typename char_type_of::type char_type; + typedef typename + mpl::if_< + is_convertible< + BOOST_DEDUCED_TYPENAME + iostreams::category_of::type, + output + >, + output, + input + >::type mode; + BOOST_STATIC_ASSERT(is_device::value); + BOOST_STATIC_ASSERT(is_device::value); + BOOST_STATIC_ASSERT(( + is_same< + char_type, + BOOST_DEDUCED_TYPENAME char_type_of::type + >::value + )); + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, + output + >::value + )); + struct category + : mode, + device_tag, + closable_tag, + flushable_tag, + localizable_tag, + optimally_buffered_tag + { }; + tee_device(device_param device, sink_param sink) + : dev_(device), sink_(sink) + { } + std::streamsize read(char_type* s, std::streamsize n) + { + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, input + >::value + )); + std::streamsize result1 = iostreams::read(dev_, s, n); + if (result1 != -1) { + std::streamsize result2 = iostreams::write(sink_, s, result1); + (void) result1; // Suppress 'unused variable' warning. + (void) result2; + BOOST_ASSERT(result1 == result2); + } + return result1; + } + std::streamsize write(const char_type* s, std::streamsize n) + { + BOOST_STATIC_ASSERT(( + is_convertible< + BOOST_DEDUCED_TYPENAME iostreams::category_of::type, output + >::value + )); + std::streamsize result1 = iostreams::write(dev_, s, n); + std::streamsize result2 = iostreams::write(sink_, s, n); + (void) result1; // Suppress 'unused variable' warning. + (void) result2; + BOOST_ASSERT(result1 == n && result2 == n); + return n; + } + void close() + { + detail::execute_all( detail::call_close_all(dev_), + detail::call_close_all(sink_) ); + } + bool flush() + { + bool r1 = iostreams::flush(dev_); + bool r2 = iostreams::flush(sink_); + return r1 && r2; + } + template + void imbue(const Locale& loc) + { + iostreams::imbue(dev_, loc); + iostreams::imbue(sink_, loc); + } + std::streamsize optimal_buffer_size() const + { + return (std::max) ( iostreams::optimal_buffer_size(dev_), + iostreams::optimal_buffer_size(sink_) ); + } +private: + device_value dev_; + sink_value sink_; +}; + +template +tee_filter tee(Sink& snk) +{ return tee_filter(snk); } + +template +tee_filter tee(const Sink& snk) +{ return tee_filter(snk); } + +template +tee_device tee(Device& dev, Sink& sink) +{ return tee_device(dev, sink); } + +template +tee_device tee(const Device& dev, Sink& sink) +{ return tee_device(dev, sink); } + +template +tee_device tee(Device& dev, const Sink& sink) +{ return tee_device(dev, sink); } + +template +tee_device tee(const Device& dev, const Sink& sink) +{ return tee_device(dev, sink); } + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_TEE_HPP_INCLUDED diff --git a/boost/iostreams/traits.hpp b/boost/iostreams/traits.hpp new file mode 100644 index 0000000..f8d7a3f --- /dev/null +++ b/boost/iostreams/traits.hpp @@ -0,0 +1,363 @@ +// (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. + +// +// Contains metafunctions char_type_of, category_of and mode_of used for +// deducing the i/o category and i/o mode of a model of Filter or Device. +// +// Also contains several utility metafunctions, functions and macros. +// + +#ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED +#define BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // stream types, char_traits. +#include // partial spec, deduced typename. +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +//----------Definitions of predicates for streams and stream buffers----------// + +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------------------// + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::basic_istream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::basic_ostream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::basic_iostream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::basic_streambuf, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ifstream, std::basic_ifstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ofstream, std::basic_ofstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_fstream, std::basic_fstream, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_filebuf, std::basic_filebuf, 2) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istringstream, std::basic_istringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostringstream, std::basic_ostringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringstream, std::basic_stringstream, 3) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_stringbuf, std::basic_stringbuf, 3) + +#else // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-----------------------// + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_istream, std::istream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_ostream, std::ostream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iostream, std::iostream, 0) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_streambuf, std::streambuf, 0) + +#endif // #ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //----------------------// + +template +struct is_std_io + : mpl::or_< is_istream, is_ostream, is_streambuf > + { }; + +template +struct is_std_file_device + : mpl::or_< + is_ifstream, + is_ofstream, + is_fstream, + is_filebuf + > + { }; + +template +struct is_std_string_device + : mpl::or_< + is_istringstream, + is_ostringstream, + is_stringstream, + is_stringbuf + > + { }; + +template +struct stream; + +template +class stream_buffer; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_stream; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class wfiltering_stream; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_streambuf; + +template< typename Mode, typename Ch, typename Tr, + typename Alloc, typename Access > +class filtering_wstreambuf; + +namespace detail { + +template +class linked_streambuf; + +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream, + boost::iostreams::stream, + 3 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_boost_stream_buffer, + boost::iostreams::stream_buffer, + 4 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_stream_impl, + boost::iostreams::filtering_stream, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstream_impl, + boost::iostreams::wfiltering_stream, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_streambuf_impl, + boost::iostreams::filtering_streambuf, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF( is_filtering_wstreambuf_impl, + boost::iostreams::filtering_wstreambuf, + 5 ) +BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_linked, linked_streambuf, 2) + +template +struct is_filtering_stream + : mpl::or_< + is_filtering_stream_impl, + is_filtering_wstream_impl + > + { }; + +template +struct is_filtering_streambuf + : mpl::or_< + is_filtering_streambuf_impl, + is_filtering_wstreambuf_impl + > + { }; + +template +struct is_boost + : mpl::or_< + is_boost_stream, + is_boost_stream_buffer, + is_filtering_stream, + is_filtering_streambuf + > + { }; + +} // End namespace detail. + +//------------------Definitions of char_type_of-------------------------------// + +namespace detail { + +template +struct member_char_type { typedef typename T::char_type type; }; + +} // End namespace detail. + +# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------// + +template +struct char_type_of + : detail::member_char_type< + typename detail::unwrapped_type::type + > + { }; + +# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------// + +template +struct char_type_of { + typedef typename detail::unwrapped_type::type U; + typedef typename + mpl::eval_if< + is_std_io, + mpl::identity, + detail::member_char_type + >::type type; +}; + +# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------// + +template +struct char_type_of< iterator_range > { + typedef typename iterator_value::type type; +}; + + +//------------------Definitions of category_of--------------------------------// + +namespace detail { + +template +struct member_category { typedef typename T::category type; }; + +} // End namespace detail. + +template +struct category_of { + template + struct member_category { + typedef typename U::category type; + }; + typedef typename detail::unwrapped_type::type U; + typedef typename + mpl::eval_if< + mpl::and_< + is_std_io, + mpl::not_< detail::is_boost > + >, + iostreams::select< // Disambiguation for Tru64 + is_filebuf, filebuf_tag, + is_ifstream, ifstream_tag, + is_ofstream, ofstream_tag, + is_fstream, fstream_tag, + is_stringbuf, stringbuf_tag, + is_istringstream, istringstream_tag, + is_ostringstream, ostringstream_tag, + is_stringstream, stringstream_tag, + is_streambuf, generic_streambuf_tag, + is_iostream, generic_iostream_tag, + is_istream, generic_istream_tag, + is_ostream, generic_ostream_tag + >, + detail::member_category + >::type type; +}; + +// Partial specialization for reference wrappers + +template +struct category_of< reference_wrapper > + : category_of + { }; + + +//------------------Definition of get_category--------------------------------// + +// +// Returns an object of type category_of::type. +// +template +inline typename category_of::type get_category(const T&) +{ typedef typename category_of::type category; return category(); } + +//------------------Definition of int_type_of---------------------------------// + +template +struct int_type_of { +#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES + typedef std::char_traits< + BOOST_DEDUCED_TYPENAME char_type_of::type + > traits_type; + typedef typename traits_type::int_type type; +#else + typedef int type; +#endif +}; + +//------------------Definition of mode_of-------------------------------------// + +namespace detail { + +template struct io_mode_impl; + +#define BOOST_IOSTREAMS_MODE_HELPER(tag_, id_) \ + case_ io_mode_impl_helper(tag_); \ + template<> struct io_mode_impl { typedef tag_ type; }; \ + /**/ +BOOST_IOSTREAMS_MODE_HELPER(input, 1) +BOOST_IOSTREAMS_MODE_HELPER(output, 2) +BOOST_IOSTREAMS_MODE_HELPER(bidirectional, 3) +BOOST_IOSTREAMS_MODE_HELPER(input_seekable, 4) +BOOST_IOSTREAMS_MODE_HELPER(output_seekable, 5) +BOOST_IOSTREAMS_MODE_HELPER(seekable, 6) +BOOST_IOSTREAMS_MODE_HELPER(dual_seekable, 7) +BOOST_IOSTREAMS_MODE_HELPER(bidirectional_seekable, 8) +BOOST_IOSTREAMS_MODE_HELPER(dual_use, 9) +#undef BOOST_IOSTREAMS_MODE_HELPER + +template +struct io_mode_id { + typedef typename category_of::type category; + BOOST_SELECT_BY_SIZE(int, value, detail::io_mode_impl_helper(category())); +}; + +} // End namespace detail. + +template // Borland 5.6.4 requires this circumlocution. +struct mode_of : detail::io_mode_impl< detail::io_mode_id::value > { }; + +// Partial specialization for reference wrappers + +template +struct mode_of< reference_wrapper > + : mode_of + { }; + + +//------------------Definition of is_device, is_filter and is_direct----------// + +namespace detail { + +template +struct has_trait_impl { + typedef typename category_of::type category; + BOOST_STATIC_CONSTANT(bool, value = (is_convertible::value)); +}; + +template +struct has_trait + : mpl::bool_::value> + { }; + +} // End namespace detail. + +template +struct is_device : detail::has_trait { }; + +template +struct is_filter : detail::has_trait { }; + +template +struct is_direct : detail::has_trait { }; + +//------------------Definition of BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS----------// + +#define BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr) \ + typedef Tr traits_type; \ + typedef typename traits_type::int_type int_type; \ + typedef typename traits_type::off_type off_type; \ + typedef typename traits_type::pos_type pos_type; \ + /**/ + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED diff --git a/boost/iostreams/traits_fwd.hpp b/boost/iostreams/traits_fwd.hpp new file mode 100644 index 0000000..a3e9526 --- /dev/null +++ b/boost/iostreams/traits_fwd.hpp @@ -0,0 +1,111 @@ +// (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. + +// Forward declarations of templates defined in traits.hpp. + +#ifndef BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED +#define BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // stream types, char_traits. + +namespace boost { namespace iostreams { + +template +struct is_istream; + +template +struct is_ostream; + +template +struct is_iostream; + +template +struct is_streambuf; + +template +struct is_istringstream; + +template +struct is_ostringstream; + +template +struct is_stringstream; + +template +struct is_stringbuf; + +template +struct is_ifstream; + +template +struct is_ofstream; + +template +struct is_fstream; + +template +struct is_filebuf; + +template +struct is_std_io; + +template +struct is_std_file_device; + +template +struct is_std_string_device; + +template +struct char_type_of; + +template +struct category_of; + +template +struct int_type_of; + +template +struct mode_of; + +template +struct is_device; + +template +struct is_filter; + +template +struct is_direct; + +namespace detail { + +template +struct is_boost_stream; + +template +struct is_boost_stream_buffer; + +template +struct is_filtering_stream; + +template +struct is_filtering_streambuf; + +template +struct is_linked; + +template +struct is_boost; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_FWD_HPP_INCLUDED diff --git a/boost/iostreams/write.hpp b/boost/iostreams/write.hpp new file mode 100644 index 0000000..8faf986 --- /dev/null +++ b/boost/iostreams/write.hpp @@ -0,0 +1,165 @@ +// (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 BOOST_IOSTREAMS_WRITE_HPP_INCLUDED +#define BOOST_IOSTREAMS_WRITE_HPP_INCLUDED + +#if defined(_MSC_VER) +# pragma once +#endif + +#include // DEDUCED_TYPENAME, MSVC. +#include +#include +#include +#include +#include // streamsize. +#include +#include +#include +#include +#include + +// Must come last. +#include + +namespace boost { namespace iostreams { + +namespace detail { + +template +struct write_device_impl; + +template +struct write_filter_impl; + +} // End namespace detail. + +template +bool put(T& t, typename char_type_of::type c) +{ return detail::write_device_impl::put(detail::unwrap(t), c); } + +template +inline std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) +{ return detail::write_device_impl::write(detail::unwrap(t), s, n); } + +template +inline std::streamsize +write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) +{ return detail::write_filter_impl::write(detail::unwrap(t), snk, s, n); } + +namespace detail { + +//------------------Definition of write_device_impl---------------------------// + +template +struct write_device_impl + : mpl::if_< + is_custom, + operations, + write_device_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, ostream_tag, streambuf_tag, output + >::type + > + >::type + { }; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type( t.rdbuf()->sputc(c), + traits_type::eof() ); + } + + template + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.rdbuf()->sputn(s, n); } +}; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { + typedef typename char_type_of::type char_type; + typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type; + return !traits_type::eq_int_type(t.sputc(c), traits_type::eof()); + } + + template + static std::streamsize write + (T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.sputn(s, n); } +}; + +template<> +struct write_device_impl { + template + static bool put(T& t, typename char_type_of::type c) + { return t.write(&c, 1) == 1; } + + template + static std::streamsize + write(T& t, const typename char_type_of::type* s, std::streamsize n) + { return t.write(s, n); } +}; + +//------------------Definition of write_filter_impl---------------------------// + +template +struct write_filter_impl + : mpl::if_< + is_custom, + operations, + write_filter_impl< + BOOST_DEDUCED_TYPENAME + dispatch< + T, multichar_tag, any_tag + >::type + > + >::type + { }; + +template<> +struct write_filter_impl { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { return t.write(snk, s, n); } +}; + +template<> +struct write_filter_impl { + template + static std::streamsize + write( T& t, Sink& snk, const typename char_type_of::type* s, + std::streamsize n ) + { + for (std::streamsize off = 0; off < n; ++off) + if (!t.put(snk, s[off])) + return off; + return n; + } +}; + +} // End namespace detail. + +} } // End namespaces iostreams, boost. + +#include + +#endif // #ifndef BOOST_IOSTREAMS_WRITE_HPP_INCLUDED diff --git a/boost/random/detail/config.hpp b/boost/random/detail/config.hpp new file mode 100644 index 0000000..724ab19 --- /dev/null +++ b/boost/random/detail/config.hpp @@ -0,0 +1,18 @@ +/* boost random/detail/config.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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 for most recent version including documentation. + * + * $Id$ + */ + +#include + +#if (defined(BOOST_NO_OPERATORS_IN_NAMESPACE) || defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS)) \ + && !defined(BOOST_MSVC) + #define BOOST_RANDOM_NO_STREAM_OPERATORS +#endif diff --git a/boost/random/detail/const_mod.hpp b/boost/random/detail/const_mod.hpp new file mode 100644 index 0000000..e0a43ab --- /dev/null +++ b/boost/random/detail/const_mod.hpp @@ -0,0 +1,216 @@ +/* boost random/detail/const_mod.hpp header file + * + * Copyright Jens Maurer 2000-2001 + * 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 for most recent version including documentation. + * + * $Id$ + * + * Revision history + * 2001-02-18 moved to individual header files + */ + +#ifndef BOOST_RANDOM_CONST_MOD_HPP +#define BOOST_RANDOM_CONST_MOD_HPP + +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace random { + +template +class const_mod +{ +public: + static IntType apply(IntType x) + { + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(x)) & (unsigned_m() - 1); + else { + IntType suppress_warnings = (m == 0); + BOOST_ASSERT(suppress_warnings == 0); + return x % (m + suppress_warnings); + } + } + + static IntType add(IntType x, IntType c) + { + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); + else if(c == 0) + return x; + else if(x < m - c) + return x + c; + else + return x - (m - c); + } + + static IntType mult(IntType a, IntType x) + { + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1); + else if(a == 0) + return 0; + else if(a == 1) + return x; + else if(m <= traits::const_max/a) // i.e. a*m <= max + return mult_small(a, x); + else if(traits::is_signed && (m%a < m/a)) + return mult_schrage(a, x); + else + return mult_general(a, x); + } + + static IntType mult_add(IntType a, IntType x, IntType c) + { + if(((unsigned_m() - 1) & unsigned_m()) == 0) + return (unsigned_type(a) * unsigned_type(x) + unsigned_type(c)) & (unsigned_m() - 1); + else if(a == 0) + return c; + else if(m <= (traits::const_max-c)/a) { // i.e. a*m+c <= max + IntType suppress_warnings = (m == 0); + BOOST_ASSERT(suppress_warnings == 0); + return (a*x+c) % (m + suppress_warnings); + } else + return add(mult(a, x), c); + } + + static IntType pow(IntType a, boost::uintmax_t exponent) + { + IntType result = 1; + while(exponent != 0) { + if(exponent % 2 == 1) { + result = mult(result, a); + } + a = mult(a, a); + exponent /= 2; + } + return result; + } + + static IntType invert(IntType x) + { return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); } + +private: + typedef integer_traits traits; + typedef typename make_unsigned::type unsigned_type; + + const_mod(); // don't instantiate + + static IntType mult_small(IntType a, IntType x) + { + IntType suppress_warnings = (m == 0); + BOOST_ASSERT(suppress_warnings == 0); + return a*x % (m + suppress_warnings); + } + + static IntType mult_schrage(IntType a, IntType value) + { + const IntType q = m / a; + const IntType r = m % a; + + BOOST_ASSERT(r < q); // check that overflow cannot happen + + return sub(a*(value%q), r*(value/q)); + } + + static IntType mult_general(IntType a, IntType b) + { + IntType suppress_warnings = (m == 0); + BOOST_ASSERT(suppress_warnings == 0); + IntType modulus = m + suppress_warnings; + BOOST_ASSERT(modulus == m); + if(::boost::uintmax_t(modulus) <= + (::std::numeric_limits< ::boost::uintmax_t>::max)() / modulus) + { + return static_cast(boost::uintmax_t(a) * b % modulus); + } else { + return static_cast(detail::mulmod(a, b, modulus)); + } + } + + static IntType sub(IntType a, IntType b) + { + if(a < b) + return m - (b - a); + else + return a - b; + } + + static unsigned_type unsigned_m() + { + if(m == 0) { + return unsigned_type((std::numeric_limits::max)()) + 1; + } else { + return unsigned_type(m); + } + } + + // invert c in the finite field (mod m) (m must be prime) + static IntType invert_euclidian(IntType c) + { + // we are interested in the gcd factor for c, because this is our inverse + BOOST_ASSERT(c > 0); + IntType l1 = 0; + IntType l2 = 1; + IntType n = c; + IntType p = m; + for(;;) { + IntType q = p / n; + l1 += q * l2; + p -= q * n; + if(p == 0) + return l2; + IntType q2 = n / p; + l2 += q2 * l1; + n -= q2 * p; + if(n == 0) + return m - l1; + } + } + + // invert c in the finite field (mod m) (c must be relatively prime to m) + static IntType invert_euclidian0(IntType c) + { + // we are interested in the gcd factor for c, because this is our inverse + BOOST_ASSERT(c > 0); + if(c == 1) return 1; + IntType l1 = 0; + IntType l2 = 1; + IntType n = c; + IntType p = m; + IntType max = (std::numeric_limits::max)(); + IntType q = max / n; + BOOST_ASSERT(max % n != n - 1 && "c must be relatively prime to m."); + l1 += q * l2; + p = max - q * n + 1; + for(;;) { + if(p == 0) + return l2; + IntType q2 = n / p; + l2 += q2 * l1; + n -= q2 * p; + if(n == 0) + return m - l1; + q = p / n; + l1 += q * l2; + p -= q * n; + } + } +}; + +} // namespace random +} // namespace boost + +#include + +#endif // BOOST_RANDOM_CONST_MOD_HPP diff --git a/boost/random/detail/disable_warnings.hpp b/boost/random/detail/disable_warnings.hpp new file mode 100644 index 0000000..4582dcb --- /dev/null +++ b/boost/random/detail/disable_warnings.hpp @@ -0,0 +1,29 @@ +/* boost random/detail/disable_warnings.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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 for most recent version including documentation. + * + * $Id$ + * + */ + +// No #include guard. This header is intended to be included multiple times. + +#include + +#ifdef BOOST_MSVC +#pragma warning(push) +#pragma warning(disable:4512) +#pragma warning(disable:4127) +#pragma warning(disable:4724) +#pragma warning(disable:4800) // 'int' : forcing value to bool 'true' or 'false' (performance warning) +#endif + +#if defined(BOOST_GCC) && BOOST_GCC >= 40600 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wlogical-op" +#endif diff --git a/boost/random/detail/enable_warnings.hpp b/boost/random/detail/enable_warnings.hpp new file mode 100644 index 0000000..24f3bb3 --- /dev/null +++ b/boost/random/detail/enable_warnings.hpp @@ -0,0 +1,22 @@ +/* boost random/detail/enable_warnings.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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 for most recent version including documentation. + * + * $Id$ + * + */ + +// No #include guard. This header is intended to be included multiple times. + +#ifdef BOOST_MSVC +#pragma warning(pop) +#endif + +#if defined(BOOST_GCC) && BOOST_GCC >= 40600 +#pragma GCC diagnostic pop +#endif diff --git a/boost/random/detail/generator_bits.hpp b/boost/random/detail/generator_bits.hpp new file mode 100644 index 0000000..0527614 --- /dev/null +++ b/boost/random/detail/generator_bits.hpp @@ -0,0 +1,36 @@ +/* boost random/detail/generator_bits.hpp header file + * + * Copyright Steven Watanabe 2011 + * 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 for most recent version including documentation. + * + * $Id$ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP +#define BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP + +#include + +namespace boost { +namespace random { +namespace detail { + +// This is a temporary measure that retains backwards +// compatibility. +template +struct generator_bits { + static std::size_t value() { + return std::numeric_limits::digits; + } +}; + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_GENERATOR_BITS_HPP diff --git a/boost/random/detail/integer_log2.hpp b/boost/random/detail/integer_log2.hpp new file mode 100644 index 0000000..2e49f28 --- /dev/null +++ b/boost/random/detail/integer_log2.hpp @@ -0,0 +1,84 @@ +/* boost random/detail/integer_log2.hpp header file + * + * Copyright Steven Watanabe 2011 + * 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 for most recent version including documentation. + * + * $Id$ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP +#define BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP + +#include +#include +#include + +namespace boost { +namespace random { +namespace detail { + +#if !defined(BOOST_NO_CXX11_CONSTEXPR) +#define BOOST_RANDOM_DETAIL_CONSTEXPR constexpr +#elif defined(BOOST_MSVC) +#define BOOST_RANDOM_DETAIL_CONSTEXPR __forceinline +#elif defined(__GNUC__) && __GNUC__ >= 4 +#define BOOST_RANDOM_DETAIL_CONSTEXPR inline __attribute__((__const__)) __attribute__((__always_inline__)) +#else +#define BOOST_RANDOM_DETAIL_CONSTEXPR inline +#endif + +template +struct integer_log2_impl +{ +#if defined(BOOST_NO_CXX11_CONSTEXPR) + template + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + int update = ((t >> Shift) != 0) * Shift; + return integer_log2_impl::apply(t >> update, accum + update); + } +#else + template + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply2(T t, int accum, int update) + { + return integer_log2_impl::apply(t >> update, accum + update); + } + + template + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + return apply2(t, accum, ((t >> Shift) != 0) * Shift); + } +#endif +}; + +template<> +struct integer_log2_impl<1> +{ + template + BOOST_RANDOM_DETAIL_CONSTEXPR static int apply(T t, int accum) + { + return int(t >> 1) + accum; + } +}; + +template +BOOST_RANDOM_DETAIL_CONSTEXPR int integer_log2(T t) +{ + return integer_log2_impl< + ::boost::detail::max_pow2_less< + ::std::numeric_limits::digits, 4 + >::value + >::apply(t, 0); +} + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_INTEGER_LOG2_HPP diff --git a/boost/random/detail/large_arithmetic.hpp b/boost/random/detail/large_arithmetic.hpp new file mode 100644 index 0000000..66f6b4e --- /dev/null +++ b/boost/random/detail/large_arithmetic.hpp @@ -0,0 +1,122 @@ +/* boost random/detail/large_arithmetic.hpp header file + * + * Copyright Steven Watanabe 2011 + * 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 for most recent version including documentation. + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP +#define BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP + +#include +#include +#include +#include + +#include + +namespace boost { +namespace random { +namespace detail { + +struct div_t { + boost::uintmax_t quotient; + boost::uintmax_t remainder; +}; + +inline div_t muldivmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ + const int bits = + ::std::numeric_limits< ::boost::uintmax_t>::digits / 2; + const ::boost::uintmax_t mask = (::boost::uintmax_t(1) << bits) - 1; + typedef ::boost::uint_t::fast digit_t; + + int shift = std::numeric_limits< ::boost::uintmax_t>::digits - 1 + - detail::integer_log2(m); + + a <<= shift; + m <<= shift; + + digit_t product[4] = { 0, 0, 0, 0 }; + digit_t a_[2] = { digit_t(a & mask), digit_t((a >> bits) & mask) }; + digit_t b_[2] = { digit_t(b & mask), digit_t((b >> bits) & mask) }; + digit_t m_[2] = { digit_t(m & mask), digit_t((m >> bits) & mask) }; + + // multiply a * b + for(int i = 0; i < 2; ++i) { + digit_t carry = 0; + for(int j = 0; j < 2; ++j) { + ::boost::uint64_t temp = ::boost::uintmax_t(a_[i]) * b_[j] + + carry + product[i + j]; + product[i + j] = digit_t(temp & mask); + carry = digit_t(temp >> bits); + } + if(carry != 0) { + product[i + 2] += carry; + } + } + + digit_t quotient[2]; + + if(m == 0) { + div_t result = { + ((::boost::uintmax_t(product[3]) << bits) | product[2]), + ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, + }; + return result; + } + + // divide product / m + for(int i = 3; i >= 2; --i) { + ::boost::uintmax_t temp = + ::boost::uintmax_t(product[i]) << bits | product[i - 1]; + + digit_t q = digit_t((product[i] == m_[1]) ? mask : temp / m_[1]); + + ::boost::uintmax_t rem = + ((temp - ::boost::uintmax_t(q) * m_[1]) << bits) + product[i - 2]; + + ::boost::uintmax_t diff = m_[0] * ::boost::uintmax_t(q); + + int error = 0; + if(diff > rem) { + if(diff - rem > m) { + error = 2; + } else { + error = 1; + } + } + q -= error; + rem = rem + error * m - diff; + + quotient[i - 2] = q; + product[i] = 0; + product[i-1] = static_cast((rem >> bits) & mask); + product[i-2] = static_cast(rem & mask); + } + + div_t result = { + ((::boost::uintmax_t(quotient[1]) << bits) | quotient[0]), + ((::boost::uintmax_t(product[1]) << bits) | product[0]) >> shift, + }; + return result; +} + +inline boost::uintmax_t muldiv(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ return detail::muldivmod(a, b, m).quotient; } + +inline boost::uintmax_t mulmod(boost::uintmax_t a, boost::uintmax_t b, boost::uintmax_t m) +{ return detail::muldivmod(a, b, m).remainder; } + +} // namespace detail +} // namespace random +} // namespace boost + +#include + +#endif // BOOST_RANDOM_DETAIL_LARGE_ARITHMETIC_HPP diff --git a/boost/random/detail/operators.hpp b/boost/random/detail/operators.hpp new file mode 100644 index 0000000..f363f37 --- /dev/null +++ b/boost/random/detail/operators.hpp @@ -0,0 +1,84 @@ +/* boost random/detail/operators.hpp header file + * + * Copyright Steven Watanabe 2010-2011 + * 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 for most recent version including documentation. + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_DETAIL_OPERATORS_HPP +#define BOOST_RANDOM_DETAIL_OPERATORS_HPP + +#include +#include + +#if BOOST_WORKAROUND(BOOST_MSVC, <= 1310) \ + || BOOST_WORKAROUND(__SUNPRO_CC, BOOST_TESTED_AT(0x5100)) + +#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ + template \ + friend std::basic_ostream& \ + operator<<(std::basic_ostream& os, const T& t) { \ + t.print(os, t); \ + return os; \ + } \ + template \ + static std::basic_ostream& \ + print(std::basic_ostream& os, const T& t) + +#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ + template \ + friend std::basic_istream& \ + operator>>(std::basic_istream& is, T& t) { \ + t.read(is, t); \ + return is; \ + } \ + template \ + static std::basic_istream& \ + read(std::basic_istream& is, T& t) + +#endif + +#if defined(BOOST_BORLANDC) + +#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ + bool operator==(const T& rhs) const \ + { return T::is_equal(*this, rhs); } \ + static bool is_equal(const T& lhs, const T& rhs) + +#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ + bool operator!=(const T& rhs) const \ + { return !T::is_equal(*this, rhs); } + +#endif + +#ifndef BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR +#define BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, T, t) \ + template \ + friend std::basic_ostream& \ + operator<<(std::basic_ostream& os, const T& t) +#endif + +#ifndef BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR +#define BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, T, t) \ + template \ + friend std::basic_istream& \ + operator>>(std::basic_istream& is, T& t) +#endif + +#ifndef BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR +#define BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(T, lhs, rhs) \ + friend bool operator==(const T& lhs, const T& rhs) +#endif + +#ifndef BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR +#define BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(T) \ + friend bool operator!=(const T& lhs, const T& rhs) \ + { return !(lhs == rhs); } +#endif + +#endif diff --git a/boost/random/detail/ptr_helper.hpp b/boost/random/detail/ptr_helper.hpp new file mode 100644 index 0000000..f1b983d --- /dev/null +++ b/boost/random/detail/ptr_helper.hpp @@ -0,0 +1,67 @@ +/* boost random/detail/ptr_helper.hpp header file + * + * Copyright Jens Maurer 2002 + * 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 for most recent version including documentation. + * + * $Id$ + * + */ + +#ifndef BOOST_RANDOM_DETAIL_PTR_HELPER_HPP +#define BOOST_RANDOM_DETAIL_PTR_HELPER_HPP + +#include + + +namespace boost { +namespace random { +namespace detail { + +// type_traits could help here, but I don't want to depend on type_traits. +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef const T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T& rvalue_type; + static reference_type ref(T& r) { return r; } + static const T& ref(const T& r) { return r; } +}; + +template +struct ptr_helper +{ + typedef T value_type; + typedef T& reference_type; + typedef T* rvalue_type; + static reference_type ref(T * p) { return *p; } + static const T& ref(const T * p) { return *p; } +}; + +} // namespace detail +} // namespace random +} // namespace boost + +// +// BOOST_RANDOM_PTR_HELPER_SPEC -- +// +// Helper macro for broken compilers defines specializations of +// ptr_helper. +// +# define BOOST_RANDOM_PTR_HELPER_SPEC(T) + +#endif // BOOST_RANDOM_DETAIL_PTR_HELPER_HPP diff --git a/boost/random/detail/seed.hpp b/boost/random/detail/seed.hpp new file mode 100644 index 0000000..d2e424a --- /dev/null +++ b/boost/random/detail/seed.hpp @@ -0,0 +1,113 @@ +/* boost random/detail/seed.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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 for most recent version including documentation. + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_DETAIL_SEED_HPP +#define BOOST_RANDOM_DETAIL_SEED_HPP + +#include + +// Sun seems to have trouble with the use of SFINAE for the +// templated constructor. So does Borland. +#if !defined(BOOST_NO_SFINAE) && !defined(__SUNPRO_CC) && !defined(BOOST_BORLANDC) + +#include +#include + +namespace boost { +namespace random { +namespace detail { + +template +struct disable_seed : boost::disable_if > {}; + +template +struct disable_constructor : disable_seed {}; + +template +struct disable_constructor {}; + +#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \ + template \ + explicit Self(Generator& gen, typename ::boost::random::detail::disable_constructor::type* = 0) + +#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \ + template \ + void seed(Generator& gen, typename ::boost::random::detail::disable_seed::type* = 0) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ + template \ + explicit Self(SeedSeq& seq, typename ::boost::random::detail::disable_constructor::type* = 0) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ + template \ + void seed(SeedSeq& seq, typename ::boost::random::detail::disable_seed::type* = 0) + +#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ + explicit Self(const T& x) + +#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \ + void seed(const T& x) +} +} +} + +#else + +#include + +#define BOOST_RANDOM_DETAIL_GENERATOR_CONSTRUCTOR(Self, Generator, gen) \ + Self(Self& other) { *this = other; } \ + Self(const Self& other) { *this = other; } \ + template \ + explicit Self(Generator& gen) { \ + boost_random_constructor_impl(gen, ::boost::is_arithmetic());\ + } \ + template \ + void boost_random_constructor_impl(Generator& gen, ::boost::false_type) + +#define BOOST_RANDOM_DETAIL_GENERATOR_SEED(Self, Generator, gen) \ + template \ + void seed(Generator& gen) { \ + boost_random_seed_impl(gen, ::boost::is_arithmetic());\ + }\ + template\ + void boost_random_seed_impl(Generator& gen, ::boost::false_type) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(Self, SeedSeq, seq) \ + Self(Self& other) { *this = other; } \ + Self(const Self& other) { *this = other; } \ + template \ + explicit Self(SeedSeq& seq) { \ + boost_random_constructor_impl(seq, ::boost::is_arithmetic());\ + } \ + template \ + void boost_random_constructor_impl(SeedSeq& seq, ::boost::false_type) + +#define BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(Self, SeedSeq, seq) \ + template \ + void seed(SeedSeq& seq) { \ + boost_random_seed_impl(seq, ::boost::is_arithmetic()); \ + } \ + template \ + void boost_random_seed_impl(SeedSeq& seq, ::boost::false_type) + +#define BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(Self, T, x) \ + explicit Self(const T& x) { boost_random_constructor_impl(x, ::boost::true_type()); }\ + void boost_random_constructor_impl(const T& x, ::boost::true_type) + +#define BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(Self, T, x) \ + void seed(const T& x) { boost_random_seed_impl(x, ::boost::true_type()); }\ + void boost_random_seed_impl(const T& x, ::boost::true_type) + +#endif + +#endif diff --git a/boost/random/detail/seed_impl.hpp b/boost/random/detail/seed_impl.hpp new file mode 100644 index 0000000..5e79582 --- /dev/null +++ b/boost/random/detail/seed_impl.hpp @@ -0,0 +1,397 @@ +/* boost random/detail/seed.hpp header file + * + * Copyright Steven Watanabe 2009 + * 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 for most recent version including documentation. + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_DETAIL_SEED_IMPL_HPP +#define BOOST_RANDOM_DETAIL_SEED_IMPL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace random { +namespace detail { + +// finds the seed type of an engine, given its +// result_type. If the result_type is integral +// the seed type is the same. If the result_type +// is floating point, the seed type is uint32_t +template +struct seed_type +{ + typedef typename boost::conditional::value, + T, + boost::uint32_t + >::type type; +}; + +template +struct const_pow_impl +{ + template + static T call(T arg, int n, T result) + { + return const_pow_impl::call(T(arg * arg), n / 2, + n%2 == 0? result : T(result * arg)); + } +}; + +template<> +struct const_pow_impl<0> +{ + template + static T call(T, int, T result) + { + return result; + } +}; + +// requires N is an upper bound on n +template +inline T const_pow(T arg, int n) { return const_pow_impl::call(arg, n, T(1)); } + +template +inline T pow2(int n) +{ + typedef unsigned int_type; + const int max_bits = std::numeric_limits::digits; + T multiplier = T(int_type(1) << (max_bits - 1)) * 2; + return (int_type(1) << (n % max_bits)) * + const_pow::digits / max_bits>(multiplier, n / max_bits); +} + +template +void generate_from_real(Engine& eng, Iter begin, Iter end) +{ + using std::fmod; + typedef typename Engine::result_type RealType; + const int Bits = detail::generator_bits::value(); + int remaining_bits = 0; + boost::uint_least32_t saved_bits = 0; + RealType multiplier = pow2( Bits); + RealType mult32 = RealType(4294967296.0); // 2^32 + while(true) { + RealType val = eng() * multiplier; + int available_bits = Bits; + // Make sure the compiler can optimize this out + // if it isn't possible. + if(Bits < 32 && available_bits < 32 - remaining_bits) { + saved_bits |= boost::uint_least32_t(val) << remaining_bits; + remaining_bits += Bits; + } else { + // If Bits < 32, then remaining_bits != 0, since + // if remaining_bits == 0, available_bits < 32 - 0, + // and we won't get here to begin with. + if(Bits < 32 || remaining_bits != 0) { + boost::uint_least32_t divisor = + (boost::uint_least32_t(1) << (32 - remaining_bits)); + boost::uint_least32_t extra_bits = boost::uint_least32_t(fmod(val, mult32)) & (divisor - 1); + val = val / divisor; + *begin++ = saved_bits | (extra_bits << remaining_bits); + if(begin == end) return; + available_bits -= 32 - remaining_bits; + remaining_bits = 0; + } + // If Bits < 32 we should never enter this loop + if(Bits >= 32) { + for(; available_bits >= 32; available_bits -= 32) { + boost::uint_least32_t word = boost::uint_least32_t(fmod(val, mult32)); + val /= mult32; + *begin++ = word; + if(begin == end) return; + } + } + remaining_bits = available_bits; + saved_bits = static_cast(val); + } + } +} + +template +void generate_from_int(Engine& eng, Iter begin, Iter end) +{ + typedef typename Engine::result_type IntType; + typedef typename boost::random::traits::make_unsigned::type unsigned_type; + int remaining_bits = 0; + boost::uint_least32_t saved_bits = 0; + unsigned_type range = boost::random::detail::subtract()((eng.max)(), (eng.min)()); + + int bits = + (range == (std::numeric_limits::max)()) ? + std::numeric_limits::digits : + detail::integer_log2(range + 1); + + { + int discarded_bits = detail::integer_log2(bits); + unsigned_type excess = (range + 1) >> (bits - discarded_bits); + if(excess != 0) { + int extra_bits = detail::integer_log2((excess - 1) ^ excess); + bits = bits - discarded_bits + extra_bits; + } + } + + unsigned_type mask = (static_cast(2) << (bits - 1)) - 1; + unsigned_type limit = ((range + 1) & ~mask) - 1; + + while(true) { + unsigned_type val; + do { + val = boost::random::detail::subtract()(eng(), (eng.min)()); + } while(limit != range && val > limit); + val &= mask; + int available_bits = bits; + if(available_bits == 32) { + *begin++ = static_cast(val) & 0xFFFFFFFFu; + if(begin == end) return; + } else if(available_bits % 32 == 0) { + for(int i = 0; i < available_bits / 32; ++i) { + boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; + int suppress_warning = (bits >= 32); + BOOST_ASSERT(suppress_warning == 1); + val >>= (32 * suppress_warning); + *begin++ = word; + if(begin == end) return; + } + } else if(bits < 32 && available_bits < 32 - remaining_bits) { + saved_bits |= boost::uint_least32_t(val) << remaining_bits; + remaining_bits += bits; + } else { + if(bits < 32 || remaining_bits != 0) { + boost::uint_least32_t extra_bits = boost::uint_least32_t(val) & ((boost::uint_least32_t(1) << (32 - remaining_bits)) - 1); + val >>= 32 - remaining_bits; + *begin++ = saved_bits | (extra_bits << remaining_bits); + if(begin == end) return; + available_bits -= 32 - remaining_bits; + remaining_bits = 0; + } + if(bits >= 32) { + for(; available_bits >= 32; available_bits -= 32) { + boost::uint_least32_t word = boost::uint_least32_t(val) & 0xFFFFFFFFu; + int suppress_warning = (bits >= 32); + BOOST_ASSERT(suppress_warning == 1); + val >>= (32 * suppress_warning); + *begin++ = word; + if(begin == end) return; + } + } + remaining_bits = available_bits; + saved_bits = static_cast(val); + } + } +} + +template +void generate_impl(Engine& eng, Iter first, Iter last, boost::true_type) +{ + return detail::generate_from_int(eng, first, last); +} + +template +void generate_impl(Engine& eng, Iter first, Iter last, boost::false_type) +{ + return detail::generate_from_real(eng, first, last); +} + +template +void generate(Engine& eng, Iter first, Iter last) +{ + return detail::generate_impl(eng, first, last, boost::random::traits::is_integral()); +} + + + +template +IntType seed_one_int(SeedSeq& seq) +{ + static const int log = ::boost::conditional<(m == 0), + ::boost::integral_constant::digits)>, + ::boost::static_log2 >::type::value; + static const int k = + (log + ((~(static_cast(2) << (log - 1)) & m)? 32 : 31)) / 32; + ::boost::uint_least32_t array[log / 32 + 4]; + seq.generate(&array[0], &array[0] + k + 3); + IntType s = 0; + for(int j = 0; j < k; ++j) { + IntType digit = const_mod::apply(IntType(array[j+3])); + IntType mult = IntType(1) << 32*j; + s = const_mod::mult_add(mult, digit, s); + } + return s; +} + +template +IntType get_one_int(Iter& first, Iter last) +{ + static const int log = ::boost::conditional<(m == 0), + ::boost::integral_constant::digits)>, + ::boost::static_log2 >::type::value; + static const int k = + (log + ((~(static_cast(2) << (log - 1)) & m)? 32 : 31)) / 32; + IntType s = 0; + for(int j = 0; j < k; ++j) { + if(first == last) { + boost::throw_exception(::std::invalid_argument("Not enough elements in call to seed.")); + } + IntType digit = const_mod::apply(IntType(*first++)); + IntType mult = IntType(1) << 32*j; + s = const_mod::mult_add(mult, digit, s); + } + return s; +} + +// TODO: work in-place whenever possible +template +void seed_array_int_impl(SeedSeq& seq, UIntType (&x)[n]) +{ + boost::uint_least32_t storage[((w+31)/32) * n]; + seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); + for(std::size_t j = 0; j < n; j++) { + UIntType val = 0; + for(std::size_t k = 0; k < (w+31)/32; ++k) { + val += static_cast(storage[(w+31)/32*j + k]) << 32*k; + } + x[j] = val & ::boost::low_bits_mask_t::sig_bits; + } +} + +template +inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::true_type) +{ + BOOST_STATIC_ASSERT_MSG(boost::is_integral::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast."); + typedef typename boost::make_unsigned::type unsigned_array[n]; + seed_array_int_impl(seq, reinterpret_cast(x)); +} + +template +inline void seed_array_int_impl(SeedSeq& seq, IntType (&x)[n], boost::false_type) +{ + seed_array_int_impl(seq, x); +} + +template +inline void seed_array_int(SeedSeq& seq, IntType (&x)[n]) +{ + seed_array_int_impl(seq, x, boost::random::traits::is_signed()); +} + +template +void fill_array_int_impl(Iter& first, Iter last, UIntType (&x)[n]) +{ + for(std::size_t j = 0; j < n; j++) { + UIntType val = 0; + for(std::size_t k = 0; k < (w+31)/32; ++k) { + if(first == last) { + boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); + } + val += static_cast(*first++) << 32*k; + } + x[j] = val & ::boost::low_bits_mask_t::sig_bits; + } +} + +template +inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::true_type) +{ + BOOST_STATIC_ASSERT_MSG(boost::is_integral::value, "Sorry but this routine has not been ported to non built-in integers as it relies on a reinterpret_cast."); + typedef typename boost::make_unsigned::type unsigned_array[n]; + fill_array_int_impl(first, last, reinterpret_cast(x)); +} + +template +inline void fill_array_int_impl(Iter& first, Iter last, IntType (&x)[n], boost::false_type) +{ + fill_array_int_impl(first, last, x); +} + +template +inline void fill_array_int(Iter& first, Iter last, IntType (&x)[n]) +{ + fill_array_int_impl(first, last, x, boost::random::traits::is_signed()); +} + +template +void seed_array_real_impl(const boost::uint_least32_t* storage, RealType (&x)[n]) +{ + boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); + RealType two32 = 4294967296.0; + const RealType divisor = RealType(1)/detail::pow2(w); + unsigned int j; + for(j = 0; j < n; ++j) { + RealType val = RealType(0); + RealType mult = divisor; + for(int k = 0; k < w/32; ++k) { + val += *storage++ * mult; + mult *= two32; + } + if(mask != 0) { + val += (*storage++ & mask) * mult; + } + BOOST_ASSERT(val >= 0); + BOOST_ASSERT(val < 1); + x[j] = val; + } +} + +template +void seed_array_real(SeedSeq& seq, RealType (&x)[n]) +{ + using std::pow; + boost::uint_least32_t storage[((w+31)/32) * n]; + seq.generate(&storage[0], &storage[0] + ((w+31)/32) * n); + seed_array_real_impl(storage, x); +} + +template +void fill_array_real(Iter& first, Iter last, RealType (&x)[n]) +{ + boost::uint_least32_t mask = ~((~boost::uint_least32_t(0)) << (w%32)); + RealType two32 = 4294967296.0; + const RealType divisor = RealType(1)/detail::pow2(w); + unsigned int j; + for(j = 0; j < n; ++j) { + RealType val = RealType(0); + RealType mult = divisor; + for(int k = 0; k < w/32; ++k, ++first) { + if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); + val += *first * mult; + mult *= two32; + } + if(mask != 0) { + if(first == last) boost::throw_exception(std::invalid_argument("Not enough elements in call to seed.")); + val += (*first & mask) * mult; + ++first; + } + BOOST_ASSERT(val >= 0); + BOOST_ASSERT(val < 1); + x[j] = val; + } +} + +} +} +} + +#include + +#endif diff --git a/boost/random/detail/signed_unsigned_tools.hpp b/boost/random/detail/signed_unsigned_tools.hpp new file mode 100644 index 0000000..1979908 --- /dev/null +++ b/boost/random/detail/signed_unsigned_tools.hpp @@ -0,0 +1,89 @@ +/* boost random/detail/signed_unsigned_tools.hpp header file + * + * Copyright Jens Maurer 2006 + * 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 for most recent version including documentation. + */ + +#ifndef BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS +#define BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS + +#include +#include +#include + +namespace boost { +namespace random { +namespace detail { + + +/* + * Compute x - y, we know that x >= y, return an unsigned value. + */ + +template::is_signed && std::numeric_limits::is_bounded> +struct subtract { }; + +template +struct subtract +{ + typedef T result_type; + result_type operator()(T x, T y) { return x - y; } +}; + +template +struct subtract +{ + typedef typename boost::random::traits::make_unsigned_or_unbounded::type result_type; + result_type operator()(T x, T y) + { + if (y >= 0) // because x >= y, it follows that x >= 0, too + return result_type(x) - result_type(y); + if (x >= 0) // y < 0 + // avoid the nasty two's complement case for y == min() + return result_type(x) + result_type(-(y+1)) + 1; + // both x and y are negative: no signed overflow + return result_type(x - y); + } +}; + +/* + * Compute x + y, x is unsigned, result fits in type of "y". + */ + +template::is_signed && (std::numeric_limits::digits >= std::numeric_limits::digits))> +struct add { }; + +template +struct add +{ + typedef T2 result_type; + result_type operator()(T1 x, T2 y) { return T2(x) + y; } +}; + +template +struct add +{ + typedef T2 result_type; + result_type operator()(T1 x, T2 y) + { + if (y >= 0) + return T2(x) + y; + // y < 0 + if (x > T1(-(y+1))) // result >= 0 after subtraction + // avoid the nasty two's complement edge case for y == min() + return T2(x - T1(-(y+1)) - 1); + // abs(x) < abs(y), thus T2 able to represent x + return T2(x) + y; + } +}; + +} // namespace detail +} // namespace random +} // namespace boost + +#endif // BOOST_RANDOM_DETAIL_SIGNED_UNSIGNED_TOOLS + diff --git a/boost/random/linear_congruential.hpp b/boost/random/linear_congruential.hpp new file mode 100644 index 0000000..62b05ec --- /dev/null +++ b/boost/random/linear_congruential.hpp @@ -0,0 +1,468 @@ +/* boost random/linear_congruential.hpp header file + * + * Copyright Jens Maurer 2000-2001 + * 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 for most recent version including documentation. + * + * $Id$ + * + * Revision history + * 2001-02-18 moved to individual header files + */ + +#ifndef BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP +#define BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace random { + +/** + * Instantiations of class template linear_congruential_engine model a + * \pseudo_random_number_generator. Linear congruential pseudo-random + * number generators are described in: + * + * @blockquote + * "Mathematical methods in large-scale computing units", D. H. Lehmer, + * Proc. 2nd Symposium on Large-Scale Digital Calculating Machines, + * Harvard University Press, 1951, pp. 141-146 + * @endblockquote + * + * Let x(n) denote the sequence of numbers returned by some pseudo-random + * number generator. Then for the linear congruential generator, + * x(n+1) := (a * x(n) + c) mod m. Parameters for the generator are + * x(0), a, c, m. The template parameter IntType shall denote an integral + * type. It must be large enough to hold values a, c, and m. The template + * parameters a and c must be smaller than m. + * + * Note: The quality of the generator crucially depends on the choice of + * the parameters. User code should use one of the sensibly parameterized + * generators such as minstd_rand instead. + */ +template +class linear_congruential_engine +{ +public: + typedef IntType result_type; + + // Required for old Boost.Random concept + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + + BOOST_STATIC_CONSTANT(IntType, multiplier = a); + BOOST_STATIC_CONSTANT(IntType, increment = c); + BOOST_STATIC_CONSTANT(IntType, modulus = m); + BOOST_STATIC_CONSTANT(IntType, default_seed = 1); + + BOOST_STATIC_ASSERT(std::numeric_limits::is_integer); + BOOST_STATIC_ASSERT(m == 0 || a < m); + BOOST_STATIC_ASSERT(m == 0 || c < m); + + /** + * Constructs a @c linear_congruential_engine, using the default seed + */ + linear_congruential_engine() { seed(); } + + /** + * Constructs a @c linear_congruential_engine, seeding it with @c x0. + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(linear_congruential_engine, + IntType, x0) + { seed(x0); } + + /** + * Constructs a @c linear_congruential_engine, seeding it with values + * produced by a call to @c seq.generate(). + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(linear_congruential_engine, + SeedSeq, seq) + { seed(seq); } + + /** + * Constructs a @c linear_congruential_engine and seeds it + * with values taken from the itrator range [first, last) + * and adjusts first to point to the element after the last one + * used. If there are not enough elements, throws @c std::invalid_argument. + * + * first and last must be input iterators. + */ + template + linear_congruential_engine(It& first, It last) + { + seed(first, last); + } + + // compiler-generated copy constructor and assignment operator are fine + + /** + * Calls seed(default_seed) + */ + void seed() { seed(default_seed); } + + /** + * If c mod m is zero and x0 mod m is zero, changes the current value of + * the generator to 1. Otherwise, changes it to x0 mod m. If c is zero, + * distinct seeds in the range [1,m) will leave the generator in distinct + * states. If c is not zero, the range is [0,m). + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(linear_congruential_engine, IntType, x0_) + { + // Work around a msvc 12/14 optimizer bug, which causes + // the line _x = 1 to run unconditionally sometimes. + // Creating a local copy seems to make it work. + IntType x0 = x0_; + // wrap _x if it doesn't fit in the destination + if(modulus == 0) { + _x = x0; + } else { + _x = x0 % modulus; + } + // handle negative seeds + if(_x < 0) { + _x += modulus; + } + // adjust to the correct range + if(increment == 0 && _x == 0) { + _x = 1; + } + BOOST_ASSERT(_x >= (min)()); + BOOST_ASSERT(_x <= (max)()); + } + + /** + * Seeds a @c linear_congruential_engine using values from a SeedSeq. + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(linear_congruential_engine, SeedSeq, seq) + { seed(detail::seed_one_int(seq)); } + + /** + * seeds a @c linear_congruential_engine with values taken + * from the itrator range [first, last) and adjusts @c first to + * point to the element after the last one used. If there are + * not enough elements, throws @c std::invalid_argument. + * + * @c first and @c last must be input iterators. + */ + template + void seed(It& first, It last) + { seed(detail::get_one_int(first, last)); } + + /** + * Returns the smallest value that the @c linear_congruential_engine + * can produce. + */ + static BOOST_CONSTEXPR result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () + { return c == 0 ? 1 : 0; } + /** + * Returns the largest value that the @c linear_congruential_engine + * can produce. + */ + static BOOST_CONSTEXPR result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () + { return modulus-1; } + + /** Returns the next value of the @c linear_congruential_engine. */ + IntType operator()() + { + _x = const_mod::mult_add(a, _x, c); + return _x; + } + + /** Fills a range with random values */ + template + void generate(Iter first, Iter last) + { detail::generate_from_int(*this, first, last); } + + /** Advances the state of the generator by @c z. */ + void discard(boost::uintmax_t z) + { + typedef const_mod mod_type; + IntType b_inv = mod_type::invert(a-1); + IntType b_gcd = mod_type::mult(a-1, b_inv); + if(b_gcd == 1) { + IntType a_z = mod_type::pow(a, z); + _x = mod_type::mult_add(a_z, _x, + mod_type::mult(mod_type::mult(c, b_inv), a_z - 1)); + } else { + // compute (a^z - 1)*c % (b_gcd * m) / (b / b_gcd) * inv(b / b_gcd) + // we're storing the intermediate result / b_gcd + IntType a_zm1_over_gcd = 0; + IntType a_km1_over_gcd = (a - 1) / b_gcd; + boost::uintmax_t exponent = z; + while(exponent != 0) { + if(exponent % 2 == 1) { + a_zm1_over_gcd = + mod_type::mult_add( + b_gcd, + mod_type::mult(a_zm1_over_gcd, a_km1_over_gcd), + mod_type::add(a_zm1_over_gcd, a_km1_over_gcd)); + } + a_km1_over_gcd = mod_type::mult_add( + b_gcd, + mod_type::mult(a_km1_over_gcd, a_km1_over_gcd), + mod_type::add(a_km1_over_gcd, a_km1_over_gcd)); + exponent /= 2; + } + + IntType a_z = mod_type::mult_add(b_gcd, a_zm1_over_gcd, 1); + IntType num = mod_type::mult(c, a_zm1_over_gcd); + b_inv = mod_type::invert((a-1)/b_gcd); + _x = mod_type::mult_add(a_z, _x, mod_type::mult(b_inv, num)); + } + } + + friend bool operator==(const linear_congruential_engine& x, + const linear_congruential_engine& y) + { return x._x == y._x; } + friend bool operator!=(const linear_congruential_engine& x, + const linear_congruential_engine& y) + { return !(x == y); } + +#if !defined(BOOST_RANDOM_NO_STREAM_OPERATORS) + /** Writes a @c linear_congruential_engine to a @c std::ostream. */ + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, + const linear_congruential_engine& lcg) + { + return os << lcg._x; + } + + /** Reads a @c linear_congruential_engine from a @c std::istream. */ + template + friend std::basic_istream& + operator>>(std::basic_istream& is, + linear_congruential_engine& lcg) + { + lcg.read(is); + return is; + } +#endif + +private: + + /// \cond show_private + + template + void read(std::basic_istream& is) { + IntType x; + if(is >> x) { + if(x >= (min)() && x <= (max)()) { + _x = x; + } else { + is.setstate(std::ios_base::failbit); + } + } + } + + /// \endcond + + IntType _x; +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool linear_congruential_engine::has_fixed_range; +template +const IntType linear_congruential_engine::multiplier; +template +const IntType linear_congruential_engine::increment; +template +const IntType linear_congruential_engine::modulus; +template +const IntType linear_congruential_engine::default_seed; +#endif + +/// \cond show_deprecated + +// provided for backwards compatibility +template +class linear_congruential : public linear_congruential_engine +{ + typedef linear_congruential_engine base_type; +public: + linear_congruential(IntType x0 = 1) : base_type(x0) {} + template + linear_congruential(It& first, It last) : base_type(first, last) {} +}; + +/// \endcond + +/** + * The specialization \minstd_rand0 was originally suggested in + * + * @blockquote + * A pseudo-random number generator for the System/360, P.A. Lewis, + * A.S. Goodman, J.M. Miller, IBM Systems Journal, Vol. 8, No. 2, + * 1969, pp. 136-146 + * @endblockquote + * + * It is examined more closely together with \minstd_rand in + * + * @blockquote + * "Random Number Generators: Good ones are hard to find", + * Stephen K. Park and Keith W. Miller, Communications of + * the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201 + * @endblockquote + */ +typedef linear_congruential_engine minstd_rand0; + +/** The specialization \minstd_rand was suggested in + * + * @blockquote + * "Random Number Generators: Good ones are hard to find", + * Stephen K. Park and Keith W. Miller, Communications of + * the ACM, Vol. 31, No. 10, October 1988, pp. 1192-1201 + * @endblockquote + */ +typedef linear_congruential_engine minstd_rand; + + +#if !defined(BOOST_NO_INT64_T) && !defined(BOOST_NO_INTEGRAL_INT64_T) +/** + * Class @c rand48 models a \pseudo_random_number_generator. It uses + * the linear congruential algorithm with the parameters a = 0x5DEECE66D, + * c = 0xB, m = 2**48. It delivers identical results to the @c lrand48() + * function available on some systems (assuming lcong48 has not been called). + * + * It is only available on systems where @c uint64_t is provided as an + * integral type, so that for example static in-class constants and/or + * enum definitions with large @c uint64_t numbers work. + */ +class rand48 +{ +public: + typedef boost::uint32_t result_type; + + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + /** + * Returns the smallest value that the generator can produce + */ + static BOOST_CONSTEXPR uint32_t min BOOST_PREVENT_MACRO_SUBSTITUTION () { return 0; } + /** + * Returns the largest value that the generator can produce + */ + static BOOST_CONSTEXPR uint32_t max BOOST_PREVENT_MACRO_SUBSTITUTION () + { return 0x7FFFFFFF; } + + /** Seeds the generator with the default seed. */ + rand48() : lcf(cnv(static_cast(1))) {} + /** + * Constructs a \rand48 generator with x(0) := (x0 << 16) | 0x330e. + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_CONSTRUCTOR(rand48, result_type, x0) + { seed(x0); } + /** + * Seeds the generator with values produced by @c seq.generate(). + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_CONSTRUCTOR(rand48, SeedSeq, seq) + { seed(seq); } + /** + * Seeds the generator using values from an iterator range, + * and updates first to point one past the last value consumed. + */ + template rand48(It& first, It last) : lcf(first, last) { } + + // compiler-generated copy ctor and assignment operator are fine + + /** Seeds the generator with the default seed. */ + void seed() { seed(static_cast(1)); } + /** + * Changes the current value x(n) of the generator to (x0 << 16) | 0x330e. + */ + BOOST_RANDOM_DETAIL_ARITHMETIC_SEED(rand48, result_type, x0) + { lcf.seed(cnv(x0)); } + /** + * Seeds the generator using values from an iterator range, + * and updates first to point one past the last value consumed. + */ + template void seed(It& first, It last) { lcf.seed(first,last); } + /** + * Seeds the generator with values produced by @c seq.generate(). + */ + BOOST_RANDOM_DETAIL_SEED_SEQ_SEED(rand48, SeedSeq, seq) + { lcf.seed(seq); } + + /** Returns the next value of the generator. */ + uint32_t operator()() { return static_cast(lcf() >> 17); } + + /** Advances the state of the generator by @c z. */ + void discard(boost::uintmax_t z) { lcf.discard(z); } + + /** Fills a range with random values */ + template + void generate(Iter first, Iter last) + { + for(; first != last; ++first) { + *first = (*this)(); + } + } + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + /** Writes a @c rand48 to a @c std::ostream. */ + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const rand48& r) + { os << r.lcf; return os; } + + /** Reads a @c rand48 from a @c std::istream. */ + template + friend std::basic_istream& + operator>>(std::basic_istream& is, rand48& r) + { is >> r.lcf; return is; } +#endif + + /** + * Returns true if the two generators will produce identical + * sequences of values. + */ + friend bool operator==(const rand48& x, const rand48& y) + { return x.lcf == y.lcf; } + /** + * Returns true if the two generators will produce different + * sequences of values. + */ + friend bool operator!=(const rand48& x, const rand48& y) + { return !(x == y); } +private: + /// \cond show_private + typedef random::linear_congruential_engine lcf_t; + lcf_t lcf; + + static boost::uint64_t cnv(boost::uint32_t x) + { return (static_cast(x) << 16) | 0x330e; } + /// \endcond +}; +#endif /* !BOOST_NO_INT64_T && !BOOST_NO_INTEGRAL_INT64_T */ + +} // namespace random + +using random::minstd_rand0; +using random::minstd_rand; +using random::rand48; + +} // namespace boost + +#include + +#endif // BOOST_RANDOM_LINEAR_CONGRUENTIAL_HPP diff --git a/boost/random/traits.hpp b/boost/random/traits.hpp new file mode 100644 index 0000000..437157c --- /dev/null +++ b/boost/random/traits.hpp @@ -0,0 +1,107 @@ +/* boost random/traits.hpp header file + * + * Copyright John Maddock 2015 + * 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 for most recent version including documentation. + * + * These traits classes serve two purposes: they are designed to mostly + * work out of the box for multiprecision types (ie number types that are + * C++ class types and not integers or floats from type-traits point of view), + * they are also a potential point of specialization for user-defined + * number types. + * + * $Id$ + */ + +#ifndef BOOST_RANDOM_TRAITS_HPP +#define BOOST_RANDOM_TRAITS_HPP + +#include +#include +#include +#include +#include + +namespace boost { +namespace random { +namespace traits { + // \cond show_private + template + struct make_unsigned_imp + { + typedef typename boost::make_unsigned::type type; + }; + template + struct make_unsigned_imp + { + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); + BOOST_STATIC_ASSERT(std::numeric_limits::is_signed == false); + BOOST_STATIC_ASSERT(std::numeric_limits::is_integer == true); + typedef T type; + }; + // \endcond + /** \brief Converts the argument type T to an unsigned type. + * + * This trait has a single member `type` which is the unsigned type corresponding to T. + * Note that + * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in + * types this trait defaults to `boost::make_unsigned::type`. For user defined types it simply asserts that + * the argument type T is an unsigned integer (using std::numeric_limits). + * User defined specializations may be provided for other cases. + */ + template + struct make_unsigned + // \cond show_private + : public make_unsigned_imp < T, boost::is_integral::value > + // \endcond + {}; + // \cond show_private + template + struct make_unsigned_or_unbounded_imp + { + typedef typename boost::make_unsigned::type type; + }; + template + struct make_unsigned_or_unbounded_imp + { + BOOST_STATIC_ASSERT(std::numeric_limits::is_specialized); + BOOST_STATIC_ASSERT((std::numeric_limits::is_signed == false) || (std::numeric_limits::is_bounded == false)); + BOOST_STATIC_ASSERT(std::numeric_limits::is_integer == true); + typedef T type; + }; + // \endcond + /** \brief Converts the argument type T to either an unsigned type or an unbounded integer type. + * + * This trait has a single member `type` which is either the unsigned type corresponding to T or an unbounded + * integer type. This trait is used to generate types suitable for the calculation of a range: as a result + * if T is signed, then member `type` *should define a type with one more bit precision than T*. For built-in + * types this trait defaults to `boost::make_unsigned::type`. For user defined types it simply asserts that + * the argument type T is either an unbounded integer, or an unsigned one (using std::numeric_limits). + * User defined specializations may be provided for other cases. + */ + template + struct make_unsigned_or_unbounded + // \cond show_private + : public make_unsigned_or_unbounded_imp < T, boost::is_integral::value > + // \endcond + {}; + /** \brief Traits class that indicates whether type T is an integer + */ + template + struct is_integral + : public integral_constant::value || (std::numeric_limits::is_integer)> + {}; + /** \brief Traits class that indicates whether type T is a signed integer + */ + template struct is_signed + : public integral_constant::value || (std::numeric_limits::is_specialized && std::numeric_limits::is_integer && std::numeric_limits::is_signed)> + {}; + +} +} +} + +#endif diff --git a/boost/random/uniform_01.hpp b/boost/random/uniform_01.hpp new file mode 100644 index 0000000..37258f5 --- /dev/null +++ b/boost/random/uniform_01.hpp @@ -0,0 +1,257 @@ +/* boost random/uniform_01.hpp header file + * + * Copyright Jens Maurer 2000-2001 + * 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 for most recent version including documentation. + * + * $Id$ + * + * Revision history + * 2001-02-18 moved to individual header files + */ + +#ifndef BOOST_RANDOM_UNIFORM_01_HPP +#define BOOST_RANDOM_UNIFORM_01_HPP + +#include +#include +#include +#include +#include +#include + +#include + +namespace boost { +namespace random { + +#ifdef BOOST_RANDOM_DOXYGEN + +/** + * The distribution function uniform_01 models a \random_distribution. + * On each invocation, it returns a random floating-point value + * uniformly distributed in the range [0..1). + * + * The template parameter RealType shall denote a float-like value type + * with support for binary operators +, -, and /. + * + * Note: The current implementation is buggy, because it may not fill + * all of the mantissa with random bits. I'm unsure how to fill a + * (to-be-invented) @c boost::bigfloat class with random bits efficiently. + * It's probably time for a traits class. + */ +template +class uniform_01 +{ +public: + typedef RealType input_type; + typedef RealType result_type; + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const; + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const; + void reset(); + + template + result_type operator()(Engine& eng); + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const new_uniform_01&) + { + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, new_uniform_01&) + { + return is; + } +#endif +}; + +#else + +namespace detail { + +template +class new_uniform_01 +{ +public: + typedef RealType input_type; + typedef RealType result_type; + // compiler-generated copy ctor and copy assignment are fine + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } + void reset() { } + + template + result_type operator()(Engine& eng) { + for (;;) { + typedef typename Engine::result_type base_result; + result_type factor = result_type(1) / + (result_type(base_result((eng.max)()-(eng.min)())) + + result_type(std::numeric_limits::is_integer ? 1 : 0)); + result_type result = result_type(base_result(eng() - (eng.min)())) * factor; + if (result < result_type(1)) + return result; + } + } + +#ifndef BOOST_RANDOM_NO_STREAM_OPERATORS + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const new_uniform_01&) + { + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, new_uniform_01&) + { + return is; + } +#endif +}; + +template +class backward_compatible_uniform_01 +{ + typedef boost::random::detail::ptr_helper traits; +public: + typedef UniformRandomNumberGenerator base_type; + typedef RealType result_type; + + BOOST_STATIC_CONSTANT(bool, has_fixed_range = false); + +#if !defined(BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS) + BOOST_STATIC_ASSERT(!std::numeric_limits::is_integer); +#endif + + explicit backward_compatible_uniform_01(typename traits::rvalue_type rng) + : _rng(rng), + _factor(result_type(1) / + (result_type((base().max)()-(base().min)()) + + result_type(std::numeric_limits::is_integer ? 1 : 0))) + { + } + // compiler-generated copy ctor and copy assignment are fine + + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(0); } + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return result_type(1); } + typename traits::value_type& base() { return traits::ref(_rng); } + const typename traits::value_type& base() const { return traits::ref(_rng); } + void reset() { } + + result_type operator()() { + for (;;) { + result_type result = result_type(base()() - (base().min)()) * _factor; + if (result < result_type(1)) + return result; + } + } + +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const backward_compatible_uniform_01& u) + { + os << u._rng; + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, backward_compatible_uniform_01& u) + { + is >> u._rng; + return is; + } +#endif + +private: + typedef typename traits::value_type::result_type base_result; + UniformRandomNumberGenerator _rng; + result_type _factor; +}; + +#ifndef BOOST_NO_INCLASS_MEMBER_INITIALIZATION +// A definition is required even for integral static constants +template +const bool backward_compatible_uniform_01::has_fixed_range; +#endif + +template::is_specialized> +struct select_uniform_01 +{ + template + struct apply + { + typedef backward_compatible_uniform_01 type; + }; +}; + +template +struct select_uniform_01 +{ + template + struct apply + { + typedef new_uniform_01 type; + }; +}; + +} + +// Because it is so commonly used: uniform distribution on the real [0..1) +// range. This allows for specializations to avoid a costly int -> float +// conversion plus float multiplication +template +class uniform_01 + : public detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type +{ + typedef typename detail::select_uniform_01::BOOST_NESTED_TEMPLATE apply::type impl_type; + typedef boost::random::detail::ptr_helper traits; +public: + + uniform_01() {} + + explicit uniform_01(typename traits::rvalue_type rng) + : impl_type(rng) + { + } + +#if !defined(BOOST_NO_OPERATORS_IN_NAMESPACE) && !defined(BOOST_NO_MEMBER_TEMPLATE_FRIENDS) + template + friend std::basic_ostream& + operator<<(std::basic_ostream& os, const uniform_01& u) + { + os << static_cast(u); + return os; + } + + template + friend std::basic_istream& + operator>>(std::basic_istream& is, uniform_01& u) + { + is >> static_cast(u); + return is; + } +#endif +}; + +#endif + +} // namespace random + +using random::uniform_01; + +} // namespace boost + +#include + +#endif // BOOST_RANDOM_UNIFORM_01_HPP diff --git a/boost/random/uniform_smallint.hpp b/boost/random/uniform_smallint.hpp new file mode 100644 index 0000000..d8f0cd3 --- /dev/null +++ b/boost/random/uniform_smallint.hpp @@ -0,0 +1,306 @@ +/* boost random/uniform_smallint.hpp header file + * + * Copyright Jens Maurer 2000-2001 + * 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 for most recent version including documentation. + * + * $Id$ + * + * Revision history + * 2001-04-08 added min +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS +#include +#endif + +namespace boost { +namespace random { + +// uniform integer distribution on a small range [min, max] + +/** + * The distribution function uniform_smallint models a \random_distribution. + * On each invocation, it returns a random integer value uniformly distributed + * in the set of integer numbers {min, min+1, min+2, ..., max}. It assumes + * that the desired range (max-min+1) is small compared to the range of the + * underlying source of random numbers and thus makes no attempt to limit + * quantization errors. + * + * Let \f$r_{\mathtt{out}} = (\mbox{max}-\mbox{min}+1)\f$ the desired range of + * integer numbers, and + * let \f$r_{\mathtt{base}}\f$ be the range of the underlying source of random + * numbers. Then, for the uniform distribution, the theoretical probability + * for any number i in the range \f$r_{\mathtt{out}}\f$ will be + * \f$\displaystyle p_{\mathtt{out}}(i) = \frac{1}{r_{\mathtt{out}}}\f$. + * Likewise, assume a uniform distribution on \f$r_{\mathtt{base}}\f$ for + * the underlying source of random numbers, i.e. + * \f$\displaystyle p_{\mathtt{base}}(i) = \frac{1}{r_{\mathtt{base}}}\f$. + * Let \f$p_{\mathtt{out\_s}}(i)\f$ denote the random + * distribution generated by @c uniform_smallint. Then the sum over all + * i in \f$r_{\mathtt{out}}\f$ of + * \f$\displaystyle + * \left(\frac{p_{\mathtt{out\_s}}(i)}{p_{\mathtt{out}}(i)} - 1\right)^2\f$ + * shall not exceed + * \f$\displaystyle \frac{r_{\mathtt{out}}}{r_{\mathtt{base}}^2} + * (r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}) + * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$. + * + * The template parameter IntType shall denote an integer-like value type. + * + * @xmlnote + * The property above is the square sum of the relative differences + * in probabilities between the desired uniform distribution + * \f$p_{\mathtt{out}}(i)\f$ and the generated distribution + * \f$p_{\mathtt{out\_s}}(i)\f$. + * The property can be fulfilled with the calculation + * \f$(\mbox{base\_rng} \mbox{ mod } r_{\mathtt{out}})\f$, as follows: + * Let \f$r = r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}\f$. + * The base distribution on \f$r_{\mathtt{base}}\f$ is folded onto the + * range \f$r_{\mathtt{out}}\f$. The numbers i < r have assigned + * \f$\displaystyle + * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor+1\f$ + * numbers of the base distribution, the rest has only \f$\displaystyle + * \left\lfloor\frac{r_{\mathtt{base}}}{r_{\mathtt{out}}}\right\rfloor\f$. + * Therefore, + * \f$\displaystyle p_{\mathtt{out\_s}}(i) = + * \left(\left\lfloor\frac{r_{\mathtt{base}}} + * {r_{\mathtt{out}}}\right\rfloor+1\right) / + * r_{\mathtt{base}}\f$ for i < r and \f$\displaystyle p_{\mathtt{out\_s}}(i) = + * \left\lfloor\frac{r_{\mathtt{base}}} + * {r_{\mathtt{out}}}\right\rfloor/r_{\mathtt{base}}\f$ otherwise. + * Substituting this in the + * above sum formula leads to the desired result. + * @endxmlnote + * + * Note: The upper bound for + * \f$(r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}}) + * (r_{\mathtt{out}} - r_{\mathtt{base}} \mbox{ mod } r_{\mathtt{out}})\f$ is + * \f$\displaystyle \frac{r_{\mathtt{out}}^2}{4}\f$. Regarding the upper bound + * for the square sum of the relative quantization error of + * \f$\displaystyle \frac{r_\mathtt{out}^3}{4r_{\mathtt{base}}^2}\f$, it + * seems wise to either choose \f$r_{\mathtt{base}}\f$ so that + * \f$r_{\mathtt{base}} > 10r_{\mathtt{out}}^2\f$ or ensure that + * \f$r_{\mathtt{base}}\f$ is + * divisible by \f$r_{\mathtt{out}}\f$. + */ +template +class uniform_smallint +{ +public: + typedef IntType input_type; + typedef IntType result_type; + + class param_type + { + public: + + typedef uniform_smallint distribution_type; + + /** constructs the parameters of a @c uniform_smallint distribution. */ + param_type(IntType min_arg = 0, IntType max_arg = 9) + : _min(min_arg), _max(max_arg) + { + BOOST_ASSERT(_min <= _max); + } + + /** Returns the minimum value. */ + IntType a() const { return _min; } + /** Returns the maximum value. */ + IntType b() const { return _max; } + + + /** Writes the parameters to a @c std::ostream. */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, param_type, parm) + { + os << parm._min << " " << parm._max; + return os; + } + + /** Reads the parameters from a @c std::istream. */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, param_type, parm) + { + is >> parm._min >> std::ws >> parm._max; + return is; + } + + /** Returns true if the two sets of parameters are equal. */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(param_type, lhs, rhs) + { return lhs._min == rhs._min && lhs._max == rhs._max; } + + /** Returns true if the two sets of parameters are different. */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(param_type) + + private: + IntType _min; + IntType _max; + }; + + /** + * Constructs a @c uniform_smallint. @c min and @c max are the + * lower and upper bounds of the output range, respectively. + */ + explicit uniform_smallint(IntType min_arg = 0, IntType max_arg = 9) + : _min(min_arg), _max(max_arg) {} + + /** + * Constructs a @c uniform_smallint from its parameters. + */ + explicit uniform_smallint(const param_type& parm) + : _min(parm.a()), _max(parm.b()) {} + + /** Returns the minimum value of the distribution. */ + result_type a() const { return _min; } + /** Returns the maximum value of the distribution. */ + result_type b() const { return _max; } + /** Returns the minimum value of the distribution. */ + result_type min BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _min; } + /** Returns the maximum value of the distribution. */ + result_type max BOOST_PREVENT_MACRO_SUBSTITUTION () const { return _max; } + + /** Returns the parameters of the distribution. */ + param_type param() const { return param_type(_min, _max); } + /** Sets the parameters of the distribution. */ + void param(const param_type& parm) + { + _min = parm.a(); + _max = parm.b(); + } + + /** + * Effects: Subsequent uses of the distribution do not depend + * on values produced by any engine prior to invoking reset. + */ + void reset() { } + + /** Returns a value uniformly distributed in the range [min(), max()]. */ + template + result_type operator()(Engine& eng) const + { + typedef typename Engine::result_type base_result; + return generate(eng, boost::random::traits::is_integral()); + } + + /** Returns a value uniformly distributed in the range [param.a(), param.b()]. */ + template + result_type operator()(Engine& eng, const param_type& parm) const + { return uniform_smallint(parm)(eng); } + + /** Writes the distribution to a @c std::ostream. */ + BOOST_RANDOM_DETAIL_OSTREAM_OPERATOR(os, uniform_smallint, ud) + { + os << ud._min << " " << ud._max; + return os; + } + + /** Reads the distribution from a @c std::istream. */ + BOOST_RANDOM_DETAIL_ISTREAM_OPERATOR(is, uniform_smallint, ud) + { + is >> ud._min >> std::ws >> ud._max; + return is; + } + + /** + * Returns true if the two distributions will produce identical + * sequences of values given equal generators. + */ + BOOST_RANDOM_DETAIL_EQUALITY_OPERATOR(uniform_smallint, lhs, rhs) + { return lhs._min == rhs._min && lhs._max == rhs._max; } + + /** + * Returns true if the two distributions may produce different + * sequences of values given equal generators. + */ + BOOST_RANDOM_DETAIL_INEQUALITY_OPERATOR(uniform_smallint) + +private: + + // \cond show_private + template + result_type generate(Engine& eng, boost::true_type) const + { + // equivalent to (eng() - eng.min()) % (_max - _min + 1) + _min, + // but guarantees no overflow. + typedef typename Engine::result_type base_result; + typedef typename boost::random::traits::make_unsigned::type base_unsigned; + typedef typename boost::random::traits::make_unsigned_or_unbounded::type range_type; +#ifdef BOOST_NO_CXX11_EXPLICIT_CONVERSION_OPERATORS + typedef typename conditional< + std::numeric_limits::is_specialized && std::numeric_limits::is_specialized + && (std::numeric_limits::digits >= std::numeric_limits::digits), + range_type, base_unsigned>::type mixed_range_type; +#else + typedef base_unsigned mixed_range_type; +#endif + range_type range = random::detail::subtract()(_max, _min); + base_unsigned base_range = + random::detail::subtract()((eng.max)(), (eng.min)()); + base_unsigned val = + random::detail::subtract()(eng(), (eng.min)()); + if(range >= base_range) { + return boost::random::detail::add()( + static_cast(val), _min); + } else { + // This involves mixed arithmetic between the base generators range + // type, and the result_type's range type. mixed_range_type is + // normally the same as base_unsigned which is the most efficient + // option, but requires a narrowing explcit cast if result_type + // is a multiprecision type. If no such casts are available then use + // multiprecision arithmetic throughout instead. + mixed_range_type modulus = static_cast(range)+1; + return boost::random::detail::add()( + static_cast(val) % modulus, _min); + } + } + + template + result_type generate(Engine& eng, boost::false_type) const + { + typedef typename Engine::result_type base_result; + typedef typename boost::random::traits::make_unsigned::type range_type; + range_type range = random::detail::subtract()(_max, _min); + base_result val = boost::uniform_01()(eng); + // what is the worst that can possibly happen here? + // base_result may not be able to represent all the values in [0, range] + // exactly. If this happens, it will cause round off error and we + // won't be able to produce all the values in the range. We don't + // care about this because the user has already told us not to by + // using uniform_smallint. However, we do need to be careful + // to clamp the result, or floating point rounding can produce + // an out of range result. + range_type offset = static_cast(val * (static_cast(range) + 1)); + if(offset > range) return _max; + return boost::random::detail::add()(offset , _min); + } + // \endcond + + result_type _min; + result_type _max; +}; + +} // namespace random + +using random::uniform_smallint; + +} // namespace boost + +#endif // BOOST_RANDOM_UNIFORM_SMALLINT_HPP diff --git a/build.cmd b/build.cmd index 7a895db..ba15591 100644 --- a/build.cmd +++ b/build.cmd @@ -32,4 +32,5 @@ bcp ^ boost/serialization/shared_ptr.hpp ^ boost/serialization/unique_ptr.hpp ^ boost/serialization/weak_ptr.hpp ^ + boost/iostreams/ ^ --boost="%1" . diff --git a/libs/iostreams/build/Jamfile.v2 b/libs/iostreams/build/Jamfile.v2 new file mode 100644 index 0000000..7ea8a96 --- /dev/null +++ b/libs/iostreams/build/Jamfile.v2 @@ -0,0 +1,129 @@ +# Boost.Iostreams Library Build Jamfile + +# (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com) +# (C) Copyright 2004-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. + +project /boost/iostreams : source-location ../src ; + +# The biggest trick in this Jamfile is to link to zlib and bzip2 when +# needed. To configure that, a number of variables are used, which must +# be set by user with 'path-constant' either in Boost's root Jamfile, or +# in user-config.jam. + +# For each library with either link to existing binary, or build +# a library from the sources. + +import modules ; +import os ; +import path ; +import ac ; +local debug = [ MATCH (--debug-configuration) : [ modules.peek : ARGV ] ] ; + +local libraries-to-install = boost_iostreams ; + +for local v in NO_COMPRESSION + NO_ZLIB + NO_BZIP2 + NO_LZMA + NO_ZSTD +{ + $(v) = [ modules.peek : $(v) ] ; +} + +if $(NO_COMPRESSION) != 1 && $(NO_ZLIB) != 1 +{ + using zlib : : boost_zlib @tag ; + zlib-requirements = + [ ac.check-library /zlib//zlib : /zlib//zlib + zlib.cpp gzip.cpp ] ; + + if [ os.environ ZLIB_SOURCE ] + { + alias boost_zlib : /zlib//zlib ; + libraries-to-install += boost_zlib ; + } +} +else +{ + if $(debug) + { + ECHO "notice: iostreams: not using zlib compression " ; + } +} + +if $(NO_COMPRESSION) != 1 && $(NO_BZIP2) != 1 +{ + using bzip2 : : boost_bzip2 @tag ; + bzip2-requirements = + [ ac.check-library /bzip2//bzip2 : /bzip2//bzip2 + bzip2.cpp ] ; + + if [ os.environ BZIP2_SOURCE ] + { + alias boost_bzip2 : /bzip2//bzip2 ; + libraries-to-install += boost_bzip2 ; + } +} +else +{ + if $(debug) + { + ECHO "notice: iostreams: not using bzip compression " ; + } +} + +if $(NO_COMPRESSION) != 1 && $(NO_LZMA) != 1 +{ + using lzma ; + + exe has_lzma_cputhreads : ../build/has_lzma_cputhreads.cpp /lzma//lzma ; + explicit has_lzma_cputhreads ; + + lzma-requirements = + [ ac.check-library /lzma//lzma : /lzma//lzma + lzma.cpp ] + [ check-target-builds has_lzma_cputhreads + : : BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED=1 ] ; +} +else +{ + if $(debug) + { + ECHO "notice: iostreams: not using lzma compression " ; + } +} + +if $(NO_COMPRESSION) != 1 && $(NO_ZSTD) != 1 +{ + using zstd ; + zstd-requirements = + [ ac.check-library /zstd//zstd : /zstd//zstd + zstd.cpp ] ; +} +else +{ + if $(debug) + { + ECHO "notice: iostreams: not using zstd compression " ; + } +} + +local sources = file_descriptor.cpp mapped_file.cpp ; + +lib boost_iostreams + : $(sources) + : shared:BOOST_IOSTREAMS_DYN_LINK=1 + BOOST_IOSTREAMS_USE_DEPRECATED + $(zlib-requirements) + $(bzip2-requirements) + $(lzma-requirements) + $(zstd-requirements) + : + : shared:BOOST_IOSTREAMS_DYN_LINK=1 + ; + +boost-install $(libraries-to-install) ; diff --git a/libs/iostreams/build/has_lzma_cputhreads.cpp b/libs/iostreams/build/has_lzma_cputhreads.cpp new file mode 100644 index 0000000..7b5a4cc --- /dev/null +++ b/libs/iostreams/build/has_lzma_cputhreads.cpp @@ -0,0 +1,10 @@ +// Copyright 2019 Peter Dimov +// Distributed under the Boost Software License, Version 1.0. +// (See accompanying file LICENSE_1_0.txt or copy at http://boost.org/LICENSE_1_0.txt) + +#include + +int main() +{ + return lzma_cputhreads(); +} diff --git a/libs/iostreams/src/bzip2.cpp b/libs/iostreams/src/bzip2.cpp new file mode 100644 index 0000000..195b57d --- /dev/null +++ b/libs/iostreams/src/bzip2.cpp @@ -0,0 +1,171 @@ +// (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. + +// To configure Boost to work with libbz2, see the +// installation instructions here: +// http://boost.org/libs/iostreams/doc/index.html?path=7 + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include +#include +#include +#include "bzlib.h" // Julian Seward's "bzip.h" header. + // To configure Boost to work with libbz2, see the + // installation instructions here: + // http://boost.org/libs/iostreams/doc/index.html?path=7 + +namespace boost { namespace iostreams { + +namespace bzip2 { + + // Status codes + +const int ok = BZ_OK; +const int run_ok = BZ_RUN_OK; +const int flush_ok = BZ_FLUSH_OK; +const int finish_ok = BZ_FINISH_OK; +const int stream_end = BZ_STREAM_END; +const int sequence_error = BZ_SEQUENCE_ERROR; +const int param_error = BZ_PARAM_ERROR; +const int mem_error = BZ_MEM_ERROR; +const int data_error = BZ_DATA_ERROR; +const int data_error_magic = BZ_DATA_ERROR_MAGIC; +const int io_error = BZ_IO_ERROR; +const int unexpected_eof = BZ_UNEXPECTED_EOF; +const int outbuff_full = BZ_OUTBUFF_FULL; +const int config_error = BZ_CONFIG_ERROR; + + // Action codes + +const int finish = BZ_FINISH; +const int run = BZ_RUN; + +} // End namespace bzip2. + +//------------------Implementation of bzip2_error-----------------------------// + +bzip2_error::bzip2_error(int error) + : BOOST_IOSTREAMS_FAILURE("bzip2 error"), error_(error) + { } + +void bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error) +{ + switch (error) { + case BZ_OK: + case BZ_RUN_OK: + case BZ_FLUSH_OK: + case BZ_FINISH_OK: + case BZ_STREAM_END: + return; + case BZ_MEM_ERROR: + boost::throw_exception(std::bad_alloc()); + default: + boost::throw_exception(bzip2_error(error)); + } +} + +//------------------Implementation of bzip2_base------------------------------// + +namespace detail { + +bzip2_base::bzip2_base(const bzip2_params& params) + : params_(params), stream_(new bz_stream), ready_(false) + { } + +bzip2_base::~bzip2_base() { delete static_cast(stream_); } + +void bzip2_base::before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ) +{ + bz_stream* s = static_cast(stream_); + s->next_in = const_cast(src_begin); + s->avail_in = static_cast(src_end - src_begin); + s->next_out = reinterpret_cast(dest_begin); + s->avail_out= static_cast(dest_end - dest_begin); +} + +void bzip2_base::after(const char*& src_begin, char*& dest_begin) +{ + bz_stream* s = static_cast(stream_); + src_begin = const_cast(s->next_in); + dest_begin = s->next_out; +} + +int bzip2_base::check_end(const char* src_begin, const char* dest_begin) +{ + bz_stream* s = static_cast(stream_); + if( src_begin == s->next_in && + s->avail_in == 0 && + dest_begin == s->next_out) { + return bzip2::unexpected_eof; + } else { + return bzip2::ok; + } +} + +int bzip2_base::end(bool compress, std::nothrow_t) +{ + if (!ready_) return bzip2::ok; + ready_ = false; + bz_stream* s = static_cast(stream_); + return compress ? BZ2_bzCompressEnd(s) : BZ2_bzDecompressEnd(s); +} + +void bzip2_base::end(bool compress) +{ + bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + end(compress, std::nothrow) + ); +} + +int bzip2_base::compress(int action) +{ + return BZ2_bzCompress(static_cast(stream_), action); +} + +int bzip2_base::decompress() +{ + return BZ2_bzDecompress(static_cast(stream_)); +} + +void bzip2_base::do_init + ( bool compress, + bzip2::alloc_func /* alloc */, + bzip2::free_func /* free */, + void* derived ) +{ + bz_stream* s = static_cast(stream_); + + // Current interface for customizing memory management + // is non-conforming and has been disabled: + // s->bzalloc = alloc; + // s->bzfree = free; + s->bzalloc = 0; + s->bzfree = 0; + s->opaque = derived; + bzip2_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + compress ? + BZ2_bzCompressInit( s, + params_.block_size, + 0, + params_.work_factor ) : + BZ2_bzDecompressInit( s, + 0, + params_.small ) + ); + ready_ = true; +} + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/file_descriptor.cpp b/libs/iostreams/src/file_descriptor.cpp new file mode 100644 index 0000000..19ed52e --- /dev/null +++ b/libs/iostreams/src/file_descriptor.cpp @@ -0,0 +1,621 @@ +// (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. + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include +#include +#include // SEEK_SET, etc. +#include // BOOST_JOIN +#include +#include +#include // BOOST_IOSTREAMS_FD_XXX +#include +#include +#include // openmodes, failure. +#include +#include +#include + +// Must come last. +#include + + // OS-specific headers for low-level i/o. + +#include // file opening flags. +#include // file access permissions. +#ifdef BOOST_IOSTREAMS_WINDOWS +# include // low-level file i/o. +# define WINDOWS_LEAN_AND_MEAN +# include +# ifndef INVALID_SET_FILE_POINTER +# define INVALID_SET_FILE_POINTER ((DWORD)-1) +# endif +#else +# include // mode_t. +# include // low-level file i/o. +#endif + +namespace boost { namespace iostreams { + +//------------------Definition of file_descriptor_impl------------------------// + +namespace detail { + +// Contains the platform dependant implementation +struct file_descriptor_impl { + // Note: These need to match file_desciptor_flags + enum flags { + never_close = 0, + close_on_exit = 1, + close_on_close = 2, + close_always = 3 + }; + + file_descriptor_impl(); + ~file_descriptor_impl(); + void open(file_handle fd, flags); +#ifdef BOOST_IOSTREAMS_WINDOWS + void open(int fd, flags); +#endif + void open(const detail::path&, BOOST_IOS::openmode); + bool is_open() const; + void close(); + void close_impl(bool close_flag, bool throw_); + std::streamsize read(char* s, std::streamsize n); + std::streamsize write(const char* s, std::streamsize n); + std::streampos seek(stream_offset off, BOOST_IOS::seekdir way); + static file_handle invalid_handle(); + file_handle handle_; + int flags_; +}; + +//------------------Implementation of file_descriptor_impl--------------------// + +file_descriptor_impl::file_descriptor_impl() + : handle_(invalid_handle()), flags_(0) + { } + +file_descriptor_impl::~file_descriptor_impl() +{ + close_impl(flags_ & close_on_exit, false); +} + +void file_descriptor_impl::open(file_handle fd, flags f) +{ + // Using 'close' to close the existing handle so that it will throw an + // exception if it fails. + // + // Only closing after assigning the new handle, so that the class will + // take ownership of the handle regardless of whether close throws. + + file_descriptor_impl tmp; + tmp.handle_ = handle_; + tmp.flags_ = flags_ & close_on_exit ? close_on_close : never_close; + + handle_ = fd; + flags_ = f; + + tmp.close(); +} + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +void file_descriptor_impl::open(int fd, flags f) +{ open(reinterpret_cast(_get_osfhandle(fd)), f); } + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +void file_descriptor_impl::open(const detail::path& p, BOOST_IOS::openmode mode) +{ + close_impl(flags_ & close_on_exit, true); + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + DWORD dwDesiredAccess; + DWORD dwCreationDisposition; + + if ( !(mode & (BOOST_IOS::in | BOOST_IOS::out | BOOST_IOS::app)) || + ((mode & BOOST_IOS::trunc) && + ((mode & BOOST_IOS::app) || !(mode & BOOST_IOS::out))) ) { + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode")); + } + else if ( mode & BOOST_IOS::in ) { + if ( mode & BOOST_IOS::app ) + { + dwCreationDisposition = OPEN_ALWAYS; + dwDesiredAccess = + GENERIC_READ | + FILE_APPEND_DATA | + FILE_WRITE_ATTRIBUTES | + FILE_WRITE_EA | + STANDARD_RIGHTS_WRITE | + SYNCHRONIZE; + } + else if ( mode & BOOST_IOS::trunc ) + { + dwCreationDisposition = CREATE_ALWAYS; + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + } + else if ( mode & BOOST_IOS::out ) + { + dwCreationDisposition = OPEN_EXISTING; + dwDesiredAccess = GENERIC_READ | GENERIC_WRITE; + } + else + { + dwCreationDisposition = OPEN_EXISTING; + dwDesiredAccess = GENERIC_READ; + } + } + else { + if ( mode & BOOST_IOS::app ) + { + dwCreationDisposition = OPEN_ALWAYS; + dwDesiredAccess = + FILE_APPEND_DATA | + FILE_WRITE_ATTRIBUTES | + FILE_WRITE_EA | + STANDARD_RIGHTS_WRITE | + SYNCHRONIZE; + } + else + { + dwCreationDisposition = CREATE_ALWAYS; + dwDesiredAccess = GENERIC_WRITE; + } + } + + + HANDLE handle = p.is_wide() ? + ::CreateFileW( p.c_wstr(), + dwDesiredAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, // lpSecurityAttributes + dwCreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL ) : // hTemplateFile + ::CreateFileA( p.c_str(), + dwDesiredAccess, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, // lpSecurityAttributes + dwCreationDisposition, + FILE_ATTRIBUTE_NORMAL, + NULL ); // hTemplateFile + if (handle != INVALID_HANDLE_VALUE) { + handle_ = handle; + flags_ = close_always; + } else { + flags_ = 0; + throw_system_failure("failed opening file"); + } +#else // #ifdef BOOST_IOSTREAMS_WINDOWS //------------------------------------// + + // Calculate oflag argument to open. + + int oflag = 0; + if ( !(mode & (BOOST_IOS::in | BOOST_IOS::out | BOOST_IOS::app)) || + ((mode & BOOST_IOS::trunc) && + ((mode & BOOST_IOS::app) || !(mode & BOOST_IOS::out))) ) { + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad open mode")); + } + else if ( mode & BOOST_IOS::in ) { + if ( mode & BOOST_IOS::app ) + oflag |= O_CREAT | O_APPEND | O_RDWR; + else if ( mode & BOOST_IOS::trunc ) + oflag |= O_CREAT | O_TRUNC | O_RDWR; + else if ( mode & BOOST_IOS::out ) + oflag |= O_RDWR; + else + oflag |= O_RDONLY; + } + else { + if ( mode & BOOST_IOS::app ) + oflag |= O_CREAT | O_APPEND | O_WRONLY; + else + oflag |= O_CREAT | O_TRUNC | O_WRONLY; + } + #ifdef _LARGEFILE64_SOURCE + oflag |= O_LARGEFILE; + #endif + + // Calculate pmode argument to open. + + mode_t pmode = S_IRUSR | S_IWUSR | + S_IRGRP | S_IWGRP | + S_IROTH | S_IWOTH; + + // Open file. + + int fd = BOOST_IOSTREAMS_FD_OPEN(p.c_str(), oflag, pmode); + if (fd == -1) { + boost::throw_exception(system_failure("failed opening file")); + } else { + if ( mode & BOOST_IOS::ate ) { + if (BOOST_IOSTREAMS_FD_SEEK(fd, 0, SEEK_END) == -1) { + BOOST_IOSTREAMS_FD_CLOSE(fd); + boost::throw_exception(system_failure("failed opening file")); + } + } + handle_ = fd; + flags_ = close_always; + } +#endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------// +} + +bool file_descriptor_impl::is_open() const +{ return handle_ != invalid_handle(); } + +void file_descriptor_impl::close() +{ + close_impl((flags_ & close_on_close) != 0, true); +} + +void file_descriptor_impl::close_impl(bool close_flag, bool throw_) { + if (handle_ != invalid_handle()) { + bool success = true; + + if (close_flag) { +#ifdef BOOST_IOSTREAMS_WINDOWS + success = ::CloseHandle(handle_) == 1; +#else + success = BOOST_IOSTREAMS_FD_CLOSE(handle_) != -1; +#endif + } + // Even if the close fails, we want nothing more to do with the handle + handle_ = invalid_handle(); + flags_ = 0; + if (!success && throw_) + throw_system_failure("failed closing file"); + } +} + +std::streamsize file_descriptor_impl::read(char* s, std::streamsize n) +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD result; + if (!::ReadFile(handle_, s, static_cast(n), &result, NULL)) + { + // report EOF if the write-side of a pipe has been closed + if (GetLastError() == ERROR_BROKEN_PIPE) + { + result = 0; + } + else + throw_system_failure("failed reading"); + } + return result == 0 ? -1 : static_cast(result); +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + errno = 0; + std::streamsize result = BOOST_IOSTREAMS_FD_READ(handle_, s, n); + if (errno != 0) + throw_system_failure("failed reading"); + return result == 0 ? -1 : result; +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +std::streamsize file_descriptor_impl::write(const char* s, std::streamsize n) +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD ignore; + if (!::WriteFile(handle_, s, static_cast(n), &ignore, NULL)) + throw_system_failure("failed writing"); + return n; +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + int amt = BOOST_IOSTREAMS_FD_WRITE(handle_, s, n); + if (amt < n) // Handles blocking fd's only. + throw_system_failure("failed writing"); + return n; +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +std::streampos file_descriptor_impl::seek + (stream_offset off, BOOST_IOS::seekdir way) +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + LONG lDistanceToMove = static_cast(off & 0xffffffff); + LONG lDistanceToMoveHigh = static_cast(off >> 32); + DWORD dwResultLow = + ::SetFilePointer( handle_, + lDistanceToMove, + &lDistanceToMoveHigh, + way == BOOST_IOS::beg ? + FILE_BEGIN : + way == BOOST_IOS::cur ? + FILE_CURRENT : + FILE_END ); + if ( dwResultLow == INVALID_SET_FILE_POINTER && + ::GetLastError() != NO_ERROR ) + { + boost::throw_exception(system_failure("failed seeking")); + } else { + return offset_to_position( + (stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow + ); + } +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + if ( off > integer_traits::const_max || + off < integer_traits::const_min ) + { + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("bad offset")); + } + stream_offset result = + BOOST_IOSTREAMS_FD_SEEK( + handle_, + static_cast(off), + ( way == BOOST_IOS::beg ? + SEEK_SET : + way == BOOST_IOS::cur ? + SEEK_CUR : + SEEK_END ) + ); + if (result == -1) + boost::throw_exception(system_failure("failed seeking")); + return offset_to_position(result); +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +// Returns the value stored in a file_handle variable when no file is open +file_handle file_descriptor_impl::invalid_handle() +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + return INVALID_HANDLE_VALUE; +#else + return -1; +#endif +} + +} // End namespace detail. + +//------------------Implementation of file_descriptor-------------------------// + +file_descriptor::file_descriptor() : pimpl_(new impl_type) { } + +file_descriptor::file_descriptor(handle_type fd, file_descriptor_flags f) + : pimpl_(new impl_type) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor::file_descriptor(handle_type fd, bool close_on_exit) + : pimpl_(new impl_type) +{ open(fd, close_on_exit); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +file_descriptor::file_descriptor(int fd, file_descriptor_flags f) + : pimpl_(new impl_type) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor::file_descriptor(int fd, bool close_on_exit) + : pimpl_(new impl_type) +{ open(fd, close_on_exit); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +file_descriptor::file_descriptor( const std::string& path, + BOOST_IOS::openmode mode ) + : pimpl_(new impl_type) +{ open(path, mode); } + +file_descriptor::file_descriptor( const char* path, + BOOST_IOS::openmode mode ) + : pimpl_(new impl_type) +{ open(path, mode); } + +file_descriptor::file_descriptor(const file_descriptor& other) + : pimpl_(other.pimpl_) + { } + +void file_descriptor::open(handle_type fd, file_descriptor_flags f) +{ pimpl_->open(fd, static_cast(f)); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor::open(handle_type fd, bool close_on_exit) +{ pimpl_->open(fd, close_on_exit ? + detail::file_descriptor_impl::close_always : + detail::file_descriptor_impl::close_on_close); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +void file_descriptor::open(int fd, file_descriptor_flags f) +{ pimpl_->open(fd, static_cast(f)); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor::open(int fd, bool close_on_exit) +{ pimpl_->open(fd, close_on_exit ? + detail::file_descriptor_impl::close_always : + detail::file_descriptor_impl::close_on_close); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +void file_descriptor::open(const std::string& path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +void file_descriptor::open(const char* path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +bool file_descriptor::is_open() const { return pimpl_->is_open(); } + +void file_descriptor::close() { pimpl_->close(); } + +std::streamsize file_descriptor::read(char_type* s, std::streamsize n) +{ return pimpl_->read(s, n); } + +std::streamsize file_descriptor::write(const char_type* s, std::streamsize n) +{ return pimpl_->write(s, n); } + +std::streampos file_descriptor::seek(stream_offset off, BOOST_IOS::seekdir way) +{ return pimpl_->seek(off, way); } + +detail::file_handle file_descriptor::handle() const { return pimpl_->handle_; } + +void file_descriptor::init() { pimpl_.reset(new impl_type); } + +void file_descriptor::open( + const detail::path& path, + BOOST_IOS::openmode mode, + BOOST_IOS::openmode base ) +{ + mode |= base; + pimpl_->open(path, mode); +} + +//------------------Implementation of file_descriptor_source------------------// + +file_descriptor_source::file_descriptor_source( + handle_type fd, file_descriptor_flags f) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor_source::file_descriptor_source( + handle_type fd, bool close_on_exit) +{ open(fd, close_on_exit); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +file_descriptor_source::file_descriptor_source(int fd, file_descriptor_flags f) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor_source::file_descriptor_source(int fd, bool close_on_exit) +{ open(fd, close_on_exit); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +file_descriptor_source::file_descriptor_source( + const std::string& path, BOOST_IOS::openmode mode) +{ open(path, mode); } + +file_descriptor_source::file_descriptor_source( + const char* path, BOOST_IOS::openmode mode) +{ open(path, mode); } + +file_descriptor_source::file_descriptor_source( + const file_descriptor_source& other) + : file_descriptor(static_cast(other)) + { } + +void file_descriptor_source::open(handle_type fd, file_descriptor_flags f) +{ file_descriptor::open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor_source::open(handle_type fd, bool close_on_exit) +{ file_descriptor::open(fd, close_on_exit); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +void file_descriptor_source::open(int fd, file_descriptor_flags f) +{ file_descriptor::open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor_source::open(int fd, bool close_on_exit) +{ file_descriptor::open(fd, close_on_exit); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +void file_descriptor_source::open( + const std::string& path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +void file_descriptor_source::open( + const char* path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +void file_descriptor_source::open( + const detail::path& path, BOOST_IOS::openmode mode) +{ + if (mode & (BOOST_IOS::out | BOOST_IOS::trunc)) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); + file_descriptor::open(path, mode, BOOST_IOS::in); +} + +//------------------Implementation of file_descriptor_sink--------------------// + +file_descriptor_sink::file_descriptor_sink( + handle_type fd, file_descriptor_flags f) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor_sink::file_descriptor_sink( + handle_type fd, bool close_on_exit) +{ open(fd, close_on_exit); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +file_descriptor_sink::file_descriptor_sink(int fd, file_descriptor_flags f) +{ open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +file_descriptor_sink::file_descriptor_sink(int fd, bool close_on_exit) +{ open(fd, close_on_exit); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +file_descriptor_sink::file_descriptor_sink( + const std::string& path, BOOST_IOS::openmode mode) +{ open(path, mode); } + +file_descriptor_sink::file_descriptor_sink( + const char* path, BOOST_IOS::openmode mode) +{ open(path, mode); } + +file_descriptor_sink::file_descriptor_sink(const file_descriptor_sink& other) + : file_descriptor(static_cast(other)) + { } + +void file_descriptor_sink::open(handle_type fd, file_descriptor_flags f) +{ file_descriptor::open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor_sink::open(handle_type fd, bool close_on_exit) +{ file_descriptor::open(fd, close_on_exit); } +#endif + +#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------// + +void file_descriptor_sink::open(int fd, file_descriptor_flags f) +{ file_descriptor::open(fd, f); } + +#if defined(BOOST_IOSTREAMS_USE_DEPRECATED) +void file_descriptor_sink::open(int fd, bool close_on_exit) +{ file_descriptor::open(fd, close_on_exit); } +#endif + +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------// + +void file_descriptor_sink::open( + const std::string& path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +void file_descriptor_sink::open( + const char* path, BOOST_IOS::openmode mode) +{ open(detail::path(path), mode); } + +void file_descriptor_sink::open( + const detail::path& path, BOOST_IOS::openmode mode) +{ + if (mode & BOOST_IOS::in) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); + file_descriptor::open(path, mode, BOOST_IOS::out); +} + +#include + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/gzip.cpp b/libs/iostreams/src/gzip.cpp new file mode 100644 index 0000000..94830e5 --- /dev/null +++ b/libs/iostreams/src/gzip.cpp @@ -0,0 +1,174 @@ +// (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. + +// To configure Boost to work with libbz2, see the +// installation instructions here: +// http://boost.org/libs/iostreams/doc/index.html?path=7 + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include +#include +#include + +namespace boost { namespace iostreams { + +//------------------Implementation of gzip_header-----------------------------// + +namespace detail { + +void gzip_header::process(char c) +{ + uint8_t value = static_cast(c); + switch (state_) { + case s_id1: + if (value != gzip::magic::id1) + boost::throw_exception(gzip_error(gzip::bad_header)); + state_ = s_id2; + break; + case s_id2: + if (value != gzip::magic::id2) + boost::throw_exception(gzip_error(gzip::bad_header)); + state_ = s_cm; + break; + case s_cm: + if (value != gzip::method::deflate) + boost::throw_exception(gzip_error(gzip::bad_method)); + state_ = s_flg; + break; + case s_flg: + flags_ = value; + state_ = s_mtime; + break; + case s_mtime: + mtime_ += value << (offset_ * 8); + if (offset_ == 3) { + state_ = s_xfl; + offset_ = 0; + } else { + ++offset_; + } + break; + case s_xfl: + state_ = s_os; + break; + case s_os: + os_ = value; + if (flags_ & gzip::flags::extra) { + state_ = s_xlen; + } else if (flags_ & gzip::flags::name) { + state_ = s_name; + } else if (flags_ & gzip::flags::comment) { + state_ = s_comment; + } else if (flags_ & gzip::flags::header_crc) { + state_ = s_hcrc; + } else { + state_ = s_done; + } + break; + case s_xlen: + xlen_ += value << (offset_ * 8); + if (offset_ == 1) { + state_ = s_extra; + offset_ = 0; + } else { + ++offset_; + } + break; + case s_extra: + if (--xlen_ == 0) { + if (flags_ & gzip::flags::name) { + state_ = s_name; + } else if (flags_ & gzip::flags::comment) { + state_ = s_comment; + } else if (flags_ & gzip::flags::header_crc) { + state_ = s_hcrc; + } else { + state_ = s_done; + } + } + break; + case s_name: + if (c != 0) { + file_name_ += c; + } else if (flags_ & gzip::flags::comment) { + state_ = s_comment; + } else if (flags_ & gzip::flags::header_crc) { + state_ = s_hcrc; + } else { + state_ = s_done; + } + break; + case s_comment: + if (c != 0) { + comment_ += c; + } else if (flags_ & gzip::flags::header_crc) { + state_ = s_hcrc; + } else { + state_ = s_done; + } + break; + case s_hcrc: + if (offset_ == 1) { + state_ = s_done; + offset_ = 0; + } else { + ++offset_; + } + break; + default: + BOOST_ASSERT(0); + } +} + +void gzip_header::reset() +{ + file_name_.clear(); + comment_.clear(); + os_ = flags_ = offset_ = xlen_ = 0; + mtime_ = 0; + state_ = s_id1; +} + +//------------------Implementation of gzip_footer-----------------------------// + +void gzip_footer::process(char c) +{ + uint8_t value = static_cast(c); + if (state_ == s_crc) { + crc_ += value << (offset_ * 8); + if (offset_ == 3) { + state_ = s_isize; + offset_ = 0; + } else { + ++offset_; + } + } else if (state_ == s_isize) { + isize_ += value << (offset_ * 8); + if (offset_ == 3) { + state_ = s_done; + offset_ = 0; + } else { + ++offset_; + } + } else { + BOOST_ASSERT(0); + } +} + +void gzip_footer::reset() +{ + crc_ = isize_ = offset_ = 0; + state_ = s_crc; +} + +} // End namespace boost::iostreams::detail. + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/lzma.cpp b/libs/iostreams/src/lzma.cpp new file mode 100644 index 0000000..9376c23 --- /dev/null +++ b/libs/iostreams/src/lzma.cpp @@ -0,0 +1,171 @@ +// (C) Copyright Milan Svoboda 2008. +// Originally developed under the fusecompress project. +// Based on bzip2.cpp by: +// (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. + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include + +#include +#include +#include + + +#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED + #if LZMA_VERSION < 50020002 + #define BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED + #endif +#endif + +namespace boost { namespace iostreams { + +namespace lzma { + + // Compression levels + +const uint32_t no_compression = 0; +const uint32_t best_speed = 1; +const uint32_t best_compression = 9; +const uint32_t default_compression = 2; + + // Status codes + +const int okay = LZMA_OK; +const int stream_end = LZMA_STREAM_END; +const int unsupported_check = LZMA_UNSUPPORTED_CHECK; +const int mem_error = LZMA_MEM_ERROR; +const int options_error = LZMA_OPTIONS_ERROR; +const int data_error = LZMA_DATA_ERROR; +const int buf_error = LZMA_BUF_ERROR; +const int prog_error = LZMA_PROG_ERROR; + + // Flush codes + +const int finish = LZMA_FINISH; +const int full_flush = LZMA_FULL_FLUSH; +const int sync_flush = LZMA_SYNC_FLUSH; +const int run = LZMA_RUN; + + // Code for current OS + +} // End namespace lzma. + +//------------------Implementation of lzma_error------------------------------// + +lzma_error::lzma_error(int error) + : BOOST_IOSTREAMS_FAILURE("lzma error"), error_(error) + { } + +void lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error) +{ + switch (error) { + case LZMA_OK: + case LZMA_STREAM_END: + return; + case LZMA_MEM_ERROR: + boost::throw_exception(std::bad_alloc()); + default: + boost::throw_exception(lzma_error(error)); + } +} + +//------------------Implementation of lzma_base-------------------------------// + +namespace detail { + +lzma_base::lzma_base() + : stream_(new lzma_stream), level_(lzma::default_compression), threads_(1) + { } + +lzma_base::~lzma_base() { delete static_cast(stream_); } + +void lzma_base::before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ) +{ + lzma_stream* s = static_cast(stream_); + s->next_in = reinterpret_cast(const_cast(src_begin)); + s->avail_in = static_cast(src_end - src_begin); + s->next_out = reinterpret_cast(dest_begin); + s->avail_out= static_cast(dest_end - dest_begin); +} + +void lzma_base::after(const char*& src_begin, char*& dest_begin, bool) +{ + lzma_stream* s = static_cast(stream_); + src_begin = const_cast(reinterpret_cast(s->next_in)); + dest_begin = reinterpret_cast(s->next_out); +} + +int lzma_base::deflate(int action) +{ + return lzma_code(static_cast(stream_), static_cast(action)); +} + +int lzma_base::inflate(int action) +{ + return lzma_code(static_cast(stream_), static_cast(action)); +} + +void lzma_base::reset(bool compress, bool realloc) +{ + lzma_stream* s = static_cast(stream_); + lzma_end(s); + if (realloc) + { + init_stream(compress); + } +} + +void lzma_base::do_init + ( const lzma_params& p, bool compress, + lzma::alloc_func, lzma::free_func, + void* ) +{ + + level_ = p.level; + threads_ = p.threads; + +#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED + if (threads_ == 0) { + threads_ = lzma_cputhreads(); + } +#endif + + init_stream(compress); +} + +void lzma_base::init_stream(bool compress) +{ + lzma_stream* s = static_cast(stream_); + + memset(s, 0, sizeof(*s)); + +#ifndef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED + const lzma_mt opt = { 0, threads_, 0, 1000, level_, NULL, LZMA_CHECK_CRC32 }; +#endif + + lzma_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + compress ? +#ifdef BOOST_IOSTREAMS_LZMA_NO_MULTITHREADED + lzma_easy_encoder(s, level_, LZMA_CHECK_CRC32) : +#else + lzma_stream_encoder_mt(s, &opt) : +#endif + lzma_stream_decoder(s, 100 * 1024 * 1024, LZMA_CONCATENATED) + ); +} + + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/mapped_file.cpp b/libs/iostreams/src/mapped_file.cpp new file mode 100644 index 0000000..918a5d4 --- /dev/null +++ b/libs/iostreams/src/mapped_file.cpp @@ -0,0 +1,499 @@ +// (C) Copyright Craig Henderson 2002 'boost/memmap.hpp' from sandbox +// (C) Copyright Jonathan Turkanis 2004. +// (C) Copyright Jonathan Graehl 2004. +// (C) Copyright Jorge Lodos 2008. +// 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.) + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef BOOST_IOSTREAMS_WINDOWS +# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers +# include +#else +# include +# include +# include // mmap, munmap. +# include +# include // struct stat. +# include // sysconf. +#endif + +namespace boost { namespace iostreams { + +namespace detail { + +// Class containing the platform-sepecific implementation +// Invariant: The members params_, data_, size_, handle_ (and mapped_handle_ +// on Windows) either +// - all have default values (or INVALID_HANDLE_VALUE for +// Windows handles), or +// - all have values reflecting a successful mapping. +// In the first case, error_ may be true, reflecting a recent unsuccessful +// open or close attempt; in the second case, error_ is always false. +class mapped_file_impl { +public: + typedef mapped_file_source::size_type size_type; + typedef mapped_file_source::param_type param_type; + typedef mapped_file_source::mapmode mapmode; + BOOST_STATIC_CONSTANT( + size_type, max_length = mapped_file_source::max_length); + mapped_file_impl(); + ~mapped_file_impl(); + void open(param_type p); + bool is_open() const { return data_ != 0; } + void close(); + bool error() const { return error_; } + mapmode flags() const { return params_.flags; } + std::size_t size() const { return static_cast(size_); } + char* data() const { return data_; } + void resize(stream_offset new_size); + static int alignment(); +private: + void open_file(param_type p); + void try_map_file(param_type p); + void map_file(param_type& p); + bool unmap_file(); + void clear(bool error); + void cleanup_and_throw(const char* msg); + param_type params_; + char* data_; + stream_offset size_; + file_handle handle_; +#ifdef BOOST_IOSTREAMS_WINDOWS + file_handle mapped_handle_; +#endif + bool error_; +}; + +mapped_file_impl::mapped_file_impl() { clear(false); } + +mapped_file_impl::~mapped_file_impl() +{ try { close(); } catch (...) { } } + +void mapped_file_impl::open(param_type p) +{ + if (is_open()) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("file already open")); + p.normalize(); + open_file(p); + map_file(p); // May modify p.hint + params_ = p; +} + +void mapped_file_impl::close() +{ + if (data_ == 0) + return; + bool error = false; + error = !unmap_file() || error; + error = + #ifdef BOOST_IOSTREAMS_WINDOWS + !::CloseHandle(handle_) + #else + ::close(handle_) != 0 + #endif + || error; + clear(error); + if (error) + throw_system_failure("failed closing mapped file"); +} + +void mapped_file_impl::resize(stream_offset new_size) +{ + if (!is_open()) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("file is closed")); + if (flags() & mapped_file::priv) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("can't resize private mapped file") + ); + if (!(flags() & mapped_file::readwrite)) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("can't resize readonly mapped file") + ); + if (params_.offset >= new_size) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("can't resize below mapped offset") + ); + if (!unmap_file()) + cleanup_and_throw("failed unmapping file"); +#ifdef BOOST_IOSTREAMS_WINDOWS + stream_offset offset = ::SetFilePointer(handle_, 0, NULL, FILE_CURRENT); + if (offset == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) + cleanup_and_throw("failed querying file pointer"); + LONG sizehigh = (new_size >> (sizeof(LONG) * 8)); + LONG sizelow = (new_size & 0xffffffff); + DWORD result = ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN); + if ((result == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) + || !::SetEndOfFile(handle_)) + cleanup_and_throw("failed resizing mapped file"); + sizehigh = (offset >> (sizeof(LONG) * 8)); + sizelow = (offset & 0xffffffff); + ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN); +#else + if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, new_size) == -1) + cleanup_and_throw("failed resizing mapped file"); +#endif + size_ = new_size; + param_type p(params_); + map_file(p); // May modify p.hint + params_ = p; +} + +int mapped_file_impl::alignment() +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + SYSTEM_INFO info; + ::GetSystemInfo(&info); + return static_cast(info.dwAllocationGranularity); +#else + return static_cast(sysconf(_SC_PAGESIZE)); +#endif +} + +void mapped_file_impl::open_file(param_type p) +{ + bool readonly = p.flags != mapped_file::readwrite; +#ifdef BOOST_IOSTREAMS_WINDOWS + + // Open file + DWORD dwDesiredAccess = + readonly ? + GENERIC_READ : + (GENERIC_READ | GENERIC_WRITE); + DWORD dwCreationDisposition = (p.new_file_size != 0 && !readonly) ? + CREATE_ALWAYS : + OPEN_EXISTING; + DWORD dwFlagsandAttributes = + readonly ? + FILE_ATTRIBUTE_READONLY : + FILE_ATTRIBUTE_TEMPORARY; + handle_ = p.path.is_wide() ? + ::CreateFileW( + p.path.c_wstr(), + dwDesiredAccess, + FILE_SHARE_READ, + NULL, + dwCreationDisposition, + dwFlagsandAttributes, + NULL ) : + ::CreateFileA( + p.path.c_str(), + dwDesiredAccess, + FILE_SHARE_READ, + NULL, + dwCreationDisposition, + dwFlagsandAttributes, + NULL ); + if (handle_ == INVALID_HANDLE_VALUE) + cleanup_and_throw("failed opening file"); + + // Set file size + if (p.new_file_size != 0 && !readonly) { + LONG sizehigh = (p.new_file_size >> (sizeof(LONG) * 8)); + LONG sizelow = (p.new_file_size & 0xffffffff); + DWORD result = ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN); + if ((result == INVALID_SET_FILE_POINTER && ::GetLastError() != NO_ERROR) + || !::SetEndOfFile(handle_)) + cleanup_and_throw("failed setting file size"); + } + + // Determine file size. Dynamically locate GetFileSizeEx for compatibility + // with old Platform SDK (thanks to Pavel Vozenilik). + typedef BOOL (WINAPI *func)(HANDLE, PLARGE_INTEGER); + HMODULE hmod = ::GetModuleHandleA("kernel32.dll"); + func get_size = + reinterpret_cast(::GetProcAddress(hmod, "GetFileSizeEx")); + if (get_size) { + LARGE_INTEGER info; + if (get_size(handle_, &info)) { + boost::intmax_t size = + ( (static_cast(info.HighPart) << 32) | + info.LowPart ); + size_ = + static_cast( + p.length != max_length ? + std::min(p.length, size) : + size + ); + } else { + cleanup_and_throw("failed querying file size"); + return; + } + } else { + DWORD hi; + DWORD low; + if ( (low = ::GetFileSize(handle_, &hi)) + != + INVALID_FILE_SIZE ) + { + boost::intmax_t size = + (static_cast(hi) << 32) | low; + size_ = + static_cast( + p.length != max_length ? + std::min(p.length, size) : + size + ); + } else { + cleanup_and_throw("failed querying file size"); + return; + } + } +#else // #ifdef BOOST_IOSTREAMS_WINDOWS + + // Open file + int flags = (readonly ? O_RDONLY : O_RDWR); + if (p.new_file_size != 0 && !readonly) + flags |= (O_CREAT | O_TRUNC); + #ifdef _LARGEFILE64_SOURCE + flags |= O_LARGEFILE; + #endif + errno = 0; + if (p.path.is_wide()) { errno = EINVAL; cleanup_and_throw("wide path not supported here"); } // happens on CYGWIN + handle_ = ::open(p.path.c_str(), flags, S_IRWXU); + if (errno != 0) + cleanup_and_throw("failed opening file"); + + //--------------Set file size---------------------------------------------// + + if (p.new_file_size != 0 && !readonly) + if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, p.new_file_size) == -1) + cleanup_and_throw("failed setting file size"); + + //--------------Determine file size---------------------------------------// + + bool success = true; + if (p.length != max_length) { + size_ = p.length; + } else { + struct BOOST_IOSTREAMS_FD_STAT info; + success = ::BOOST_IOSTREAMS_FD_FSTAT(handle_, &info) != -1; + size_ = info.st_size; + } + if (!success) + cleanup_and_throw("failed querying file size"); +#endif // #ifdef BOOST_IOSTREAMS_WINDOWS +} + +void mapped_file_impl::try_map_file(param_type p) +{ + bool priv = p.flags == mapped_file::priv; + bool readonly = p.flags == mapped_file::readonly; +#ifdef BOOST_IOSTREAMS_WINDOWS + + // Create mapping + DWORD protect = priv ? + PAGE_WRITECOPY : + readonly ? + PAGE_READONLY : + PAGE_READWRITE; + mapped_handle_ = + ::CreateFileMappingA( + handle_, + NULL, + protect, + 0, + 0, + NULL ); + if (mapped_handle_ == NULL) + cleanup_and_throw("failed create mapping"); + + // Access data + DWORD access = priv ? + FILE_MAP_COPY : + readonly ? + FILE_MAP_READ : + FILE_MAP_WRITE; + void* data = + ::MapViewOfFileEx( + mapped_handle_, + access, + (DWORD) (p.offset >> 32), + (DWORD) (p.offset & 0xffffffff), + (SIZE_T) (numeric_cast(size_) != max_length ? size_ : 0), + (LPVOID) p.hint ); + if (!data) + cleanup_and_throw("failed mapping view"); +#else + void* data = + ::BOOST_IOSTREAMS_FD_MMAP( + const_cast(p.hint), + size_, + readonly ? PROT_READ : (PROT_READ | PROT_WRITE), + priv ? MAP_PRIVATE : MAP_SHARED, + handle_, + p.offset ); + if (data == MAP_FAILED) + cleanup_and_throw("failed mapping file"); +#endif + data_ = static_cast(data); +} + +void mapped_file_impl::map_file(param_type& p) +{ + try { + try_map_file(p); + } catch (const std::exception&) { + if (p.hint) { + p.hint = 0; + try_map_file(p); + } else { + throw; + } + } +} + +bool mapped_file_impl::unmap_file() +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + bool error = false; + error = !::UnmapViewOfFile(data_) || error; + error = !::CloseHandle(mapped_handle_) || error; + mapped_handle_ = NULL; + return !error; +#else + return ::munmap(data_, size_) == 0; +#endif +} + +void mapped_file_impl::clear(bool error) +{ + params_ = param_type(); + data_ = 0; + size_ = 0; +#ifdef BOOST_IOSTREAMS_WINDOWS + handle_ = INVALID_HANDLE_VALUE; + mapped_handle_ = NULL; +#else + handle_ = 0; +#endif + error_ = error; +} + +// Called when an error is encountered during the execution of open_file or +// map_file +void mapped_file_impl::cleanup_and_throw(const char* msg) +{ +#ifdef BOOST_IOSTREAMS_WINDOWS + DWORD error = GetLastError(); + if (mapped_handle_ != NULL) + ::CloseHandle(mapped_handle_); + if (handle_ != INVALID_HANDLE_VALUE) + ::CloseHandle(handle_); + SetLastError(error); +#else + int error = errno; + if (handle_ != 0) + ::close(handle_); + errno = error; +#endif + clear(true); + boost::iostreams::detail::throw_system_failure(msg); +} + +//------------------Implementation of mapped_file_params_base-----------------// + +void mapped_file_params_base::normalize() +{ + if (mode && flags) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE( + "at most one of 'mode' and 'flags' may be specified" + )); + if (flags) { + switch (flags) { + case mapped_file::readonly: + case mapped_file::readwrite: + case mapped_file::priv: + break; + default: + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags")); + } + } else { + flags = (mode & BOOST_IOS::out) ? + mapped_file::readwrite : + mapped_file::readonly; + mode = BOOST_IOS::openmode(); + } + if (offset < 0) + boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid offset")); + if (new_file_size < 0) + boost::throw_exception( + BOOST_IOSTREAMS_FAILURE("invalid new file size") + ); +} + +} // End namespace detail. + +//------------------Implementation of mapped_file_source----------------------// + +mapped_file_source::mapped_file_source() + : pimpl_(new impl_type) + { } + +mapped_file_source::mapped_file_source(const mapped_file_source& other) + : pimpl_(other.pimpl_) + { } + +bool mapped_file_source::is_open() const +{ return pimpl_->is_open(); } + +void mapped_file_source::close() { pimpl_->close(); } + +// safe_bool is explicitly qualified below to please msvc 7.1 +mapped_file_source::operator mapped_file_source::safe_bool() const +{ return pimpl_->error() ? &safe_bool_helper::x : 0; } + +bool mapped_file_source::operator!() const +{ return pimpl_->error(); } + +mapped_file_source::mapmode mapped_file_source::flags() const +{ return pimpl_->flags(); } + +mapped_file_source::size_type mapped_file_source::size() const +{ return pimpl_->size(); } + +const char* mapped_file_source::data() const { return pimpl_->data(); } + +const char* mapped_file_source::begin() const { return data(); } + +const char* mapped_file_source::end() const { return data() + size(); } +int mapped_file_source::alignment() +{ return detail::mapped_file_impl::alignment(); } + +void mapped_file_source::init() { pimpl_.reset(new impl_type); } + +void mapped_file_source::open_impl(const param_type& p) +{ pimpl_->open(p); } + +//------------------Implementation of mapped_file-----------------------------// + +mapped_file::mapped_file(const mapped_file& other) + : delegate_(other.delegate_) + { } + +void mapped_file::resize(stream_offset new_size) +{ delegate_.pimpl_->resize(new_size); } + +//------------------Implementation of mapped_file_sink------------------------// + +mapped_file_sink::mapped_file_sink(const mapped_file_sink& other) + : mapped_file(static_cast(other)) + { } + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/zlib.cpp b/libs/iostreams/src/zlib.cpp new file mode 100644 index 0000000..6638068 --- /dev/null +++ b/libs/iostreams/src/zlib.cpp @@ -0,0 +1,188 @@ +// (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. + +// To configure Boost to work with zlib, see the +// installation instructions here: +// http://boost.org/libs/iostreams/doc/index.html?path=7 + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include +#include +#include +#include "zlib.h" // Jean-loup Gailly's and Mark Adler's "zlib.h" header. + // To configure Boost to work with zlib, see the + // installation instructions here: + // http://boost.org/libs/iostreams/doc/index.html?path=7 + +namespace boost { namespace iostreams { + +namespace zlib { + + // Compression levels + +const int no_compression = Z_NO_COMPRESSION; +const int best_speed = Z_BEST_SPEED; +const int best_compression = Z_BEST_COMPRESSION; +const int default_compression = Z_DEFAULT_COMPRESSION; + + // Compression methods + +const int deflated = Z_DEFLATED; + + // Compression strategies + +const int default_strategy = Z_DEFAULT_STRATEGY; +const int filtered = Z_FILTERED; +const int huffman_only = Z_HUFFMAN_ONLY; + + // Status codes + +const int okay = Z_OK; +const int stream_end = Z_STREAM_END; +const int stream_error = Z_STREAM_ERROR; +const int version_error = Z_VERSION_ERROR; +const int data_error = Z_DATA_ERROR; +const int mem_error = Z_MEM_ERROR; +const int buf_error = Z_BUF_ERROR; + + // Flush codes + +const int finish = Z_FINISH; +const int no_flush = Z_NO_FLUSH; +const int sync_flush = Z_SYNC_FLUSH; + + // Code for current OS + +//const int os_code = OS_CODE; + +} // End namespace zlib. + +//------------------Implementation of zlib_error------------------------------// + +zlib_error::zlib_error(int error) + : BOOST_IOSTREAMS_FAILURE("zlib error"), error_(error) + { } + +void zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(int error) +{ + switch (error) { + case Z_OK: + case Z_STREAM_END: + //case Z_BUF_ERROR: + return; + case Z_MEM_ERROR: + boost::throw_exception(std::bad_alloc()); + default: + boost::throw_exception(zlib_error(error)); + ; + } +} + +//------------------Implementation of zlib_base-------------------------------// + +namespace detail { + +zlib_base::zlib_base() + : stream_(new z_stream), calculate_crc_(false), crc_(0), crc_imp_(0), + total_in_(0), total_out_(0) + { } + +zlib_base::~zlib_base() { delete static_cast(stream_); } + +void zlib_base::before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ) +{ + z_stream* s = static_cast(stream_); + s->next_in = reinterpret_cast(const_cast(src_begin)); + s->avail_in = static_cast(src_end - src_begin); + s->next_out = reinterpret_cast(dest_begin); + s->avail_out= static_cast(dest_end - dest_begin); +} + +void zlib_base::after(const char*& src_begin, char*& dest_begin, bool compress) +{ + z_stream* s = static_cast(stream_); + const char* next_in = reinterpret_cast(s->next_in); + char* next_out = reinterpret_cast(s->next_out); + if (calculate_crc_) { + const zlib::byte* buf = compress ? + reinterpret_cast(src_begin) : + reinterpret_cast( + const_cast(dest_begin) + ); + zlib::uint length = compress ? + static_cast(next_in - src_begin) : + static_cast(next_out - dest_begin); + crc_ = crc_imp_ = crc32(crc_imp_, buf, length); + } + total_in_ = s->total_in; + total_out_ = s->total_out; + src_begin = next_in; + dest_begin = next_out; +} + +int zlib_base::xdeflate(int flush) +{ + return ::deflate(static_cast(stream_), flush); +} + +int zlib_base::xinflate(int flush) +{ + return ::inflate(static_cast(stream_), flush); +} + +void zlib_base::reset(bool compress, bool realloc) +{ + z_stream* s = static_cast(stream_); + // Undiagnosed bug: + // deflateReset(), etc., return Z_DATA_ERROR + //zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + realloc ? + (compress ? deflateReset(s) : inflateReset(s)) : + (compress ? deflateEnd(s) : inflateEnd(s)) + ; + //); + crc_imp_ = 0; +} + +void zlib_base::do_init + ( const zlib_params& p, bool compress, + zlib::xalloc_func /* alloc */, zlib::xfree_func /* free*/, + void* derived ) +{ + calculate_crc_ = p.calculate_crc; + z_stream* s = static_cast(stream_); + + // Current interface for customizing memory management + // is non-conforming and has been disabled: + // s->zalloc = alloc; + // s->zfree = free; + s->zalloc = 0; + s->zfree = 0; + s->opaque = derived; + int window_bits = p.noheader? -p.window_bits : p.window_bits; + zlib_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + compress ? + deflateInit2( s, + p.level, + p.method, + window_bits, + p.mem_level, + p.strategy ) : + inflateInit2(s, window_bits) + ); +} + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost. diff --git a/libs/iostreams/src/zstd.cpp b/libs/iostreams/src/zstd.cpp new file mode 100644 index 0000000..20cc009 --- /dev/null +++ b/libs/iostreams/src/zstd.cpp @@ -0,0 +1,166 @@ +// (C) Copyright Reimar Döffinger 2018. +// Based on zstd.cpp by: +// (C) Copyright Milan Svoboda 2008. +// (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. + +// Define BOOST_IOSTREAMS_SOURCE so that +// knows that we are building the library (possibly exporting code), rather +// than using it (possibly importing code). +#define BOOST_IOSTREAMS_SOURCE + +#include + +#include +#include +#include + +namespace boost { namespace iostreams { + +namespace zstd { + // Compression levels + +const uint32_t best_speed = 1; +const uint32_t best_compression = 19; +const uint32_t default_compression = 3; + + // Status codes + +const int okay = 0; +const int stream_end = 1; + + // Flush codes + +const int finish = 0; +const int flush = 1; +const int run = 2; +} // End namespace zstd. + +//------------------Implementation of zstd_error------------------------------// + +zstd_error::zstd_error(size_t error) + : BOOST_IOSTREAMS_FAILURE(ZSTD_getErrorName(error)), error_(error) + { } + +void zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(size_t error) +{ + if (ZSTD_isError(error)) + boost::throw_exception(zstd_error(error)); +} + +//------------------Implementation of zstd_base-------------------------------// + +namespace detail { + +zstd_base::zstd_base() + : cstream_(ZSTD_createCStream()), dstream_(ZSTD_createDStream()), in_(new ZSTD_inBuffer), out_(new ZSTD_outBuffer), eof_(0) + { } + +zstd_base::~zstd_base() +{ + ZSTD_freeCStream(static_cast(cstream_)); + ZSTD_freeDStream(static_cast(dstream_)); + delete static_cast(in_); + delete static_cast(out_); +} + +void zstd_base::before( const char*& src_begin, const char* src_end, + char*& dest_begin, char* dest_end ) +{ + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + in->src = src_begin; + in->size = static_cast(src_end - src_begin); + in->pos = 0; + out->dst = dest_begin; + out->size = static_cast(dest_end - dest_begin); + out->pos = 0; +} + +void zstd_base::after(const char*& src_begin, char*& dest_begin, bool) +{ + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + src_begin = reinterpret_cast(in->src) + in->pos; + dest_begin = reinterpret_cast(out->dst) + out->pos; +} + +int zstd_base::deflate(int action) +{ + ZSTD_CStream *s = static_cast(cstream_); + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + // Ignore spurious extra calls. + // Note size > 0 will trigger an error in this case. + if (eof_ && in->size == 0) return zstd::stream_end; + size_t result = ZSTD_compressStream(s, out, in); + zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + if (action != zstd::run) + { + result = action == zstd::finish ? ZSTD_endStream(s, out) : ZSTD_flushStream(s, out); + zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + eof_ = action == zstd::finish && result == 0; + return result == 0 ? zstd::stream_end : zstd::okay; + } + return zstd::okay; +} + +int zstd_base::inflate(int action) +{ + ZSTD_DStream *s = static_cast(dstream_); + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + // need loop since iostream code cannot handle short reads + do { + size_t result = ZSTD_decompressStream(s, out, in); + zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION(result); + } while (in->pos < in->size && out->pos < out->size); + return action == zstd::finish && in->size == 0 && out->pos == 0 ? zstd::stream_end : zstd::okay; +} + +void zstd_base::reset(bool compress, bool realloc) +{ + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + if (realloc) + { + memset(in, 0, sizeof(*in)); + memset(out, 0, sizeof(*out)); + eof_ = 0; + + zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + compress ? + ZSTD_initCStream(static_cast(cstream_), level) : + ZSTD_initDStream(static_cast(dstream_)) + ); + } +} + +void zstd_base::do_init + ( const zstd_params& p, bool compress, + zstd::alloc_func, zstd::free_func, + void* ) +{ + ZSTD_inBuffer *in = static_cast(in_); + ZSTD_outBuffer *out = static_cast(out_); + + memset(in, 0, sizeof(*in)); + memset(out, 0, sizeof(*out)); + eof_ = 0; + + level = p.level; + zstd_error::check BOOST_PREVENT_MACRO_SUBSTITUTION( + compress ? + ZSTD_initCStream(static_cast(cstream_), level) : + ZSTD_initDStream(static_cast(dstream_)) + ); +} + +} // End namespace detail. + +//----------------------------------------------------------------------------// + +} } // End namespaces iostreams, boost.