Add boost::iostreams
This commit is contained in:
parent
66937ea62d
commit
93fbc5de96
595
boost/core/bit.hpp
Normal file
595
boost/core/bit.hpp
Normal file
@ -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 <bit>
|
||||
//
|
||||
// Copyright 2020 Peter Dimov
|
||||
// Distributed under the Boost Software License, Version 1.0.
|
||||
// https://www.boost.org/LICENSE_1_0.txt
|
||||
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <limits>
|
||||
#include <cstring>
|
||||
|
||||
#if defined(_MSC_VER)
|
||||
|
||||
# include <intrin.h>
|
||||
# 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<class To, class From>
|
||||
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<unsigned int>::digits - std::numeric_limits<unsigned char>::digits ): std::numeric_limits<unsigned char>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned short x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clz( x ) - ( std::numeric_limits<unsigned int>::digits - std::numeric_limits<unsigned short>::digits ): std::numeric_limits<unsigned short>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned int x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clz( x ): std::numeric_limits<unsigned int>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( unsigned long x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clzl( x ): std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countl_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_clzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
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<int>( 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<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
return static_cast<boost::uint32_t>( x >> 32 ) != 0?
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x >> 32 ) ):
|
||||
boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) + 32;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 24;
|
||||
}
|
||||
|
||||
inline int countl_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) ) - 16;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
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<boost::uint8_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint16_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::countl_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countl_one( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::countl_zero( static_cast<T>( ~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<unsigned char>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned short x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctz( x ): std::numeric_limits<unsigned short>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned int x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctz( x ): std::numeric_limits<unsigned int>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( unsigned long x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctzl( x ): std::numeric_limits<unsigned long>::digits;
|
||||
}
|
||||
|
||||
BOOST_CONSTEXPR inline int countr_impl( boost::ulong_long_type x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return x? __builtin_ctzll( x ): std::numeric_limits<boost::ulong_long_type>::digits;
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
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<int>( 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<int>( r );
|
||||
}
|
||||
else
|
||||
{
|
||||
return 64;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
return static_cast<boost::uint32_t>( x ) != 0?
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) ):
|
||||
boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x >> 32 ) ) + 32;
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint8_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x100 );
|
||||
}
|
||||
|
||||
inline int countr_impl( boost::uint16_t x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) | 0x10000 );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
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<boost::uint8_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint16_t) )
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint16_t>( x ) );
|
||||
}
|
||||
else BOOST_IF_CONSTEXPR ( sizeof(T) == sizeof(boost::uint32_t) )
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::countr_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
template<class T>
|
||||
BOOST_CONSTEXPR int countr_one( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return boost::core::countr_zero( static_cast<T>( ~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<class T>
|
||||
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<unsigned>( ( 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<unsigned>( ( x * 0x0101010101010101 ) >> 56 );
|
||||
}
|
||||
|
||||
} // namespace detail
|
||||
|
||||
template<class T>
|
||||
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<boost::uint32_t>( x ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return boost::core::detail::popcount_impl( static_cast<boost::uint64_t>( x ) );
|
||||
}
|
||||
}
|
||||
|
||||
#endif // defined(__GNUC__) || defined(__clang__)
|
||||
|
||||
// rotating
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR T rotl( T x, int s ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned const mask = std::numeric_limits<T>::digits - 1;
|
||||
return x << (s & mask) | x >> ((-s) & mask);
|
||||
}
|
||||
|
||||
template<class T>
|
||||
BOOST_CXX14_CONSTEXPR T rotr( T x, int s ) BOOST_NOEXCEPT
|
||||
{
|
||||
unsigned const mask = std::numeric_limits<T>::digits - 1;
|
||||
return x >> (s & mask) | x << ((-s) & mask);
|
||||
}
|
||||
|
||||
// integral powers of 2
|
||||
|
||||
template<class T>
|
||||
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<class T>
|
||||
BOOST_CONSTEXPR T bit_width( T x ) BOOST_NOEXCEPT
|
||||
{
|
||||
return static_cast<T>(
|
||||
std::numeric_limits<T>::digits - boost::core::countl_zero( x ) );
|
||||
}
|
||||
|
||||
template<class T>
|
||||
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<class T>
|
||||
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<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint32_t>( x ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
return static_cast<T>( boost::core::detail::bit_ceil_impl( static_cast<boost::uint64_t>( 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
|
117
boost/integer/integer_log2.hpp
Normal file
117
boost/integer/integer_log2.hpp
Normal file
@ -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 <climits>
|
||||
#include <limits>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/assert.hpp>
|
||||
#include <boost/cstdint.hpp>
|
||||
#include <boost/core/bit.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/make_unsigned.hpp>
|
||||
|
||||
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<const T>, 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
|
134
boost/integer/integer_mask.hpp
Normal file
134
boost/integer/integer_mask.hpp
Normal file
@ -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 <boost/integer_fwd.hpp> // self include
|
||||
|
||||
#include <boost/config.hpp> // for BOOST_STATIC_CONSTANT
|
||||
#include <boost/integer.hpp> // for boost::uint_t
|
||||
|
||||
#include <climits> // for UCHAR_MAX, etc.
|
||||
#include <cstddef> // for std::size_t
|
||||
|
||||
#include <boost/limits.hpp> // 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<Bits>::least least;
|
||||
typedef typename uint_t<Bits>::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<Type>::digits > { \
|
||||
typedef std::numeric_limits<Type> limits_type; \
|
||||
typedef uint_t<limits_type::digits>::least least; \
|
||||
typedef uint_t<limits_type::digits>::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
|
175
boost/iostreams/categories.hpp
Normal file
175
boost/iostreams/categories.hpp
Normal file
@ -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
|
594
boost/iostreams/chain.hpp
Normal file
594
boost/iostreams/chain.hpp
Normal file
@ -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 <boost/assert.hpp>
|
||||
#include <exception>
|
||||
#include <iterator> // advance.
|
||||
#include <list>
|
||||
#include <memory> // allocator, auto_ptr or unique_ptr.
|
||||
#include <stdexcept> // logic_error, out_of_range.
|
||||
#include <boost/checked_delete.hpp>
|
||||
#include <boost/config.hpp> // BOOST_MSVC, template friends,
|
||||
#include <boost/detail/workaround.hpp> // BOOST_NESTED_TEMPLATE
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
#include <boost/iostreams/constants.hpp>
|
||||
#include <boost/iostreams/detail/access_control.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/push.hpp>
|
||||
#include <boost/iostreams/detail/streambuf.hpp> // pubsync.
|
||||
#include <boost/iostreams/detail/wrap_unwrap.hpp>
|
||||
#include <boost/iostreams/device/null.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/iostreams/traits.hpp> // is_filter.
|
||||
#include <boost/iostreams/stream_buffer.hpp>
|
||||
#include <boost/next_prior.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
|
||||
// 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 <cstring>
|
||||
# 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<typename Chain> 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<typename T>
|
||||
// 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<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
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<Self> client_type;
|
||||
friend class chain_client<Self>;
|
||||
private:
|
||||
typedef linked_streambuf<Ch> streambuf_type;
|
||||
typedef std::list<streambuf_type*> list_type;
|
||||
typedef chain_base<Self, Ch, Tr, Alloc, Mode> 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<mode, dual_use>::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<size_type>(n) >= size())
|
||||
boost::throw_exception(std::out_of_range("bad chain offset"));
|
||||
return (*boost::next(list().begin(), n))->component_type();
|
||||
}
|
||||
|
||||
// Deprecated.
|
||||
template<int N>
|
||||
const boost::core::typeinfo& component_type() const { return component_type(N); }
|
||||
|
||||
template<typename T>
|
||||
T* component(int n) const { return component(n, boost::type<T>()); }
|
||||
|
||||
// Deprecated.
|
||||
template<int N, typename T>
|
||||
T* component() const { return component<T>(N); }
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, == 1310)
|
||||
private:
|
||||
#endif
|
||||
template<typename T>
|
||||
T* component(int n, boost::type<T>) const
|
||||
{
|
||||
if (static_cast<size_type>(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<T*>(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<typename T>
|
||||
void push_impl(const T& t, std::streamsize buffer_size = -1,
|
||||
std::streamsize pback_size = -1)
|
||||
{
|
||||
typedef typename iostreams::category_of<T>::type category;
|
||||
typedef typename unwrap_ios<T>::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<category, Mode>::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<streambuf_t>
|
||||
buf(new streambuf_t(t, buffer_size, pback_size));
|
||||
|
||||
#else
|
||||
|
||||
std::unique_ptr<streambuf_t>
|
||||
buf(new streambuf_t(t, buffer_size, pback_size));
|
||||
|
||||
#endif
|
||||
|
||||
list().push_back(buf.get());
|
||||
buf.release();
|
||||
if (is_device<component_type>::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<Mode, output>::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<Ch, Mode> > null;
|
||||
if ((flags_ & f_complete) == 0) {
|
||||
null.open(basic_null_device<Ch, Mode>());
|
||||
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<chain_impl> 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<Ch> > \
|
||||
class name_ : public boost::iostreams::detail::chain_base< \
|
||||
name_<Mode, Ch, Tr, Alloc>, \
|
||||
Ch, Tr, Alloc, Mode \
|
||||
> \
|
||||
{ \
|
||||
public: \
|
||||
struct category : device_tag, Mode { }; \
|
||||
typedef Mode mode; \
|
||||
private: \
|
||||
typedef boost::iostreams::detail::chain_base< \
|
||||
name_<Mode, Ch, Tr, Alloc>, \
|
||||
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<typename Chain>
|
||||
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<int N>
|
||||
const boost::core::typeinfo& component_type() const
|
||||
{ return chain_->BOOST_NESTED_TEMPLATE component_type<N>(); }
|
||||
|
||||
template<typename T>
|
||||
T* component(int n) const
|
||||
{ return chain_->BOOST_NESTED_TEMPLATE component<T>(n); }
|
||||
|
||||
// Deprecated.
|
||||
template<int N, typename T>
|
||||
T* component() const
|
||||
{ return chain_->BOOST_NESTED_TEMPLATE component<N, T>(); }
|
||||
|
||||
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<typename T>
|
||||
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<typename S, typename C, typename T, typename A, typename M>
|
||||
friend class chain_base;
|
||||
#else
|
||||
public:
|
||||
#endif
|
||||
virtual void notify() { }
|
||||
private:
|
||||
chain_type* chain_;
|
||||
};
|
||||
|
||||
//--------------Implementation of chain_base----------------------------------//
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
inline std::streamsize chain_base<Self, Ch, Tr, Alloc, Mode>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{ return iostreams::read(*list().front(), s, n); }
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
inline std::streamsize chain_base<Self, Ch, Tr, Alloc, Mode>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{ return iostreams::write(*list().front(), s, n); }
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
inline std::streampos chain_base<Self, Ch, Tr, Alloc, Mode>::seek
|
||||
(stream_offset off, BOOST_IOS::seekdir way)
|
||||
{ return iostreams::seek(*list().front(), off, way); }
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
void chain_base<Self, Ch, Tr, Alloc, Mode>::reset()
|
||||
{
|
||||
using namespace std;
|
||||
pimpl_->close();
|
||||
pimpl_->reset();
|
||||
}
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
bool chain_base<Self, Ch, Tr, Alloc, Mode>::is_complete() const
|
||||
{
|
||||
return (pimpl_->flags_ & f_complete) != 0;
|
||||
}
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
bool chain_base<Self, Ch, Tr, Alloc, Mode>::auto_close() const
|
||||
{
|
||||
return (pimpl_->flags_ & f_auto_close) != 0;
|
||||
}
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
void chain_base<Self, Ch, Tr, Alloc, Mode>::set_auto_close(bool close)
|
||||
{
|
||||
pimpl_->flags_ =
|
||||
(pimpl_->flags_ & ~f_auto_close) |
|
||||
(close ? f_auto_close : 0);
|
||||
}
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
bool chain_base<Self, Ch, Tr, Alloc, Mode>::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<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
void chain_base<Self, Ch, Tr, Alloc, Mode>::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
|
73
boost/iostreams/char_traits.hpp
Normal file
73
boost/iostreams/char_traits.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <cstddef>
|
||||
#include <cstdio> // EOF.
|
||||
#include <string> // std::char_traits.
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
|
||||
# include <cwchar>
|
||||
#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<typename Ch>
|
||||
struct char_traits;
|
||||
|
||||
template<>
|
||||
struct char_traits<char> : 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<wchar_t> : std::char_traits<wchar_t> {
|
||||
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
|
158
boost/iostreams/checked_operations.hpp
Normal file
158
boost/iostreams/checked_operations.hpp
Normal file
@ -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 <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/dispatch.hpp>
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/detail/config/unreachable_return.hpp>
|
||||
#include <boost/iostreams/get.hpp>
|
||||
#include <boost/iostreams/put.hpp>
|
||||
#include <boost/iostreams/read.hpp>
|
||||
#include <boost/iostreams/seek.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/write.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct read_write_if_impl;
|
||||
|
||||
template<typename T>
|
||||
struct seek_if_impl;
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename T>
|
||||
typename int_type_of<T>::type get_if(T& t)
|
||||
{
|
||||
typedef typename detail::dispatch<T, input, output>::type tag;
|
||||
return detail::read_write_if_impl<tag>::get(t);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::streamsize
|
||||
read_if(T& t, typename char_type_of<T>::type* s, std::streamsize n)
|
||||
{
|
||||
typedef typename detail::dispatch<T, input, output>::type tag;
|
||||
return detail::read_write_if_impl<tag>::read(t, s, n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
bool put_if(T& t, typename char_type_of<T>::type c)
|
||||
{
|
||||
typedef typename detail::dispatch<T, output, input>::type tag;
|
||||
return detail::read_write_if_impl<tag>::put(t, c);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
inline std::streamsize write_if
|
||||
(T& t, const typename char_type_of<T>::type* s, std::streamsize n)
|
||||
{
|
||||
typedef typename detail::dispatch<T, output, input>::type tag;
|
||||
return detail::read_write_if_impl<tag>::write(t, s, n);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
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<T, random_access, any_tag>::type tag;
|
||||
return seek_if_impl<tag>::seek(t, off, way, which);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
//------------------Specializations of read_write_if_impl---------------------//
|
||||
|
||||
template<>
|
||||
struct read_write_if_impl<input> {
|
||||
template<typename T>
|
||||
static typename int_type_of<T>::type get(T& t)
|
||||
{ return iostreams::get(t); }
|
||||
|
||||
template<typename T>
|
||||
static std::streamsize
|
||||
read(T& t, typename char_type_of<T>::type* s, std::streamsize n)
|
||||
{ return iostreams::read(t, s, n); }
|
||||
|
||||
template<typename T>
|
||||
static bool put(T&, typename char_type_of<T>::type)
|
||||
{ boost::throw_exception(cant_write());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(false) }
|
||||
|
||||
template<typename T>
|
||||
static std::streamsize
|
||||
write(T&, const typename char_type_of<T>::type*, std::streamsize)
|
||||
{ boost::throw_exception(cant_write());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct read_write_if_impl<output> {
|
||||
template<typename T>
|
||||
static typename int_type_of<T>::type get(T&)
|
||||
{ boost::throw_exception(cant_read());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
|
||||
template<typename T>
|
||||
static std::streamsize
|
||||
read(T&, typename char_type_of<T>::type*, std::streamsize)
|
||||
{ boost::throw_exception(cant_read());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
|
||||
template<typename T>
|
||||
static bool put(T& t, typename char_type_of<T>::type c)
|
||||
{ return iostreams::put(t, c); }
|
||||
|
||||
template<typename T>
|
||||
static std::streamsize
|
||||
write( T& t, const typename char_type_of<T>::type* s,
|
||||
std::streamsize n )
|
||||
{ return iostreams::write(t, s, n); }
|
||||
};
|
||||
|
||||
//------------------Specializations of seek_if_impl---------------------------//
|
||||
|
||||
template<>
|
||||
struct seek_if_impl<random_access> {
|
||||
template<typename T>
|
||||
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<any_tag> {
|
||||
template<typename T>
|
||||
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 <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHECKED_OPERATIONS_HPP_INCLUDED
|
253
boost/iostreams/close.hpp
Normal file
253
boost/iostreams/close.hpp
Normal file
@ -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 <boost/config.hpp> // DEDUCED_TYPENAME, MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/flush.hpp>
|
||||
#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // BOOST_IOS
|
||||
#include <boost/iostreams/detail/select.hpp>
|
||||
#include <boost/iostreams/detail/wrap_unwrap.hpp>
|
||||
#include <boost/iostreams/operations_fwd.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_integral.hpp>
|
||||
#include <boost/type_traits/remove_cv.hpp>
|
||||
#include <boost/type_traits/remove_reference.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template<typename T>
|
||||
void close(T& t);
|
||||
|
||||
template<typename T>
|
||||
void close(T& t, BOOST_IOS::openmode which);
|
||||
|
||||
template<typename T, typename Sink>
|
||||
void close(T& t, Sink& snk, BOOST_IOS::openmode which);
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename T>
|
||||
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<typename T, typename Sink>
|
||||
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<typename T>
|
||||
struct close_impl;
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename T>
|
||||
void close(T& t) { detail::close_all(t); }
|
||||
|
||||
template<typename T>
|
||||
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<T>::close(detail::unwrap(t), which);
|
||||
}
|
||||
|
||||
template<typename T, typename Sink>
|
||||
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<T>::close(detail::unwrap(t), snk, which);
|
||||
}
|
||||
|
||||
namespace detail {
|
||||
|
||||
//------------------Definition of close_impl----------------------------------//
|
||||
|
||||
struct close_boost_stream { };
|
||||
struct close_filtering_stream { };
|
||||
|
||||
template<typename T>
|
||||
struct close_tag {
|
||||
typedef typename category_of<T>::type category;
|
||||
typedef typename detail::unwrapped_type<T>::type unwrapped;
|
||||
typedef typename
|
||||
iostreams::select<
|
||||
mpl::not_< is_convertible<category, closable_tag> >,
|
||||
any_tag,
|
||||
mpl::or_<
|
||||
is_boost_stream<unwrapped>,
|
||||
is_boost_stream_buffer<unwrapped>
|
||||
>,
|
||||
close_boost_stream,
|
||||
mpl::or_<
|
||||
is_filtering_stream<unwrapped>,
|
||||
is_filtering_streambuf<unwrapped>
|
||||
>,
|
||||
close_filtering_stream,
|
||||
mpl::or_<
|
||||
is_convertible<category, two_sequence>,
|
||||
is_convertible<category, dual_use>
|
||||
>,
|
||||
two_sequence,
|
||||
else_,
|
||||
closable_tag
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct close_impl
|
||||
: mpl::if_<
|
||||
is_custom<T>,
|
||||
operations<T>,
|
||||
close_impl<BOOST_DEDUCED_TYPENAME close_tag<T>::type>
|
||||
>::type
|
||||
{ };
|
||||
|
||||
template<>
|
||||
struct close_impl<any_tag> {
|
||||
template<typename T>
|
||||
static void close(T& t, BOOST_IOS::openmode which)
|
||||
{
|
||||
if (which == BOOST_IOS::out)
|
||||
iostreams::flush(t);
|
||||
}
|
||||
|
||||
template<typename T, typename Sink>
|
||||
static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
||||
{
|
||||
if (which == BOOST_IOS::out) {
|
||||
non_blocking_adapter<Sink> nb(snk);
|
||||
iostreams::flush(t, nb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct close_impl<close_boost_stream> {
|
||||
template<typename T>
|
||||
static void close(T& t)
|
||||
{
|
||||
t.close();
|
||||
}
|
||||
template<typename T>
|
||||
static void close(T& t, BOOST_IOS::openmode which)
|
||||
{
|
||||
if (which == BOOST_IOS::out)
|
||||
t.close();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct close_impl<close_filtering_stream> {
|
||||
template<typename T>
|
||||
static void close(T& t, BOOST_IOS::openmode which)
|
||||
{
|
||||
typedef typename category_of<T>::type category;
|
||||
const bool in = is_convertible<category, input>::value &&
|
||||
!is_convertible<category, output>::value;
|
||||
if (in == (which == BOOST_IOS::in) && t.is_complete())
|
||||
t.pop();
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct close_impl<closable_tag> {
|
||||
template<typename T>
|
||||
static void close(T& t, BOOST_IOS::openmode which)
|
||||
{
|
||||
typedef typename category_of<T>::type category;
|
||||
const bool in = is_convertible<category, input>::value &&
|
||||
!is_convertible<category, output>::value;
|
||||
if (in == (which == BOOST_IOS::in))
|
||||
t.close();
|
||||
}
|
||||
template<typename T, typename Sink>
|
||||
static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
||||
{
|
||||
typedef typename category_of<T>::type category;
|
||||
const bool in = is_convertible<category, input>::value &&
|
||||
!is_convertible<category, output>::value;
|
||||
if (in == (which == BOOST_IOS::in)) {
|
||||
non_blocking_adapter<Sink> nb(snk);
|
||||
t.close(nb);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct close_impl<two_sequence> {
|
||||
template<typename T>
|
||||
static void close(T& t, BOOST_IOS::openmode which) { t.close(which); }
|
||||
template<typename T, typename Sink>
|
||||
static void close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
||||
{
|
||||
non_blocking_adapter<Sink> nb(snk);
|
||||
t.close(nb, which);
|
||||
}
|
||||
};
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_CLOSE_HPP_INCLUDED
|
417
boost/iostreams/code_converter.hpp
Normal file
417
boost/iostreams/code_converter.hpp
Normal file
@ -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 <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#if defined(BOOST_IOSTREAMS_NO_WIDE_STREAMS) || \
|
||||
defined(BOOST_IOSTREAMS_NO_LOCALE) \
|
||||
/**/
|
||||
# error code conversion not supported on this platform
|
||||
#endif
|
||||
|
||||
#include <algorithm> // max.
|
||||
#include <cstring> // memcpy.
|
||||
#include <exception>
|
||||
#include <boost/config.hpp> // DEDUCED_TYPENAME,
|
||||
#include <boost/iostreams/char_traits.hpp>
|
||||
#include <boost/iostreams/constants.hpp> // default_filter_buffer_size.
|
||||
#include <boost/iostreams/detail/adapter/concept_adapter.hpp>
|
||||
#include <boost/iostreams/detail/adapter/direct_adapter.hpp>
|
||||
#include <boost/iostreams/detail/buffer.hpp>
|
||||
#include <boost/iostreams/detail/call_traits.hpp>
|
||||
#include <boost/iostreams/detail/codecvt_holder.hpp>
|
||||
#include <boost/iostreams/detail/codecvt_helper.hpp>
|
||||
#include <boost/iostreams/detail/double_object.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
#include <boost/iostreams/detail/forward.hpp>
|
||||
#include <boost/iostreams/detail/functional.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // failure, openmode, int types, streamsize.
|
||||
#include <boost/iostreams/detail/optional.hpp>
|
||||
#include <boost/iostreams/detail/select.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // 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<bool B>
|
||||
struct strncpy_if_same_impl;
|
||||
|
||||
template<>
|
||||
struct strncpy_if_same_impl<true> {
|
||||
template<typename Ch>
|
||||
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<false> {
|
||||
template<typename Src, typename Tgt>
|
||||
static Tgt* copy(Tgt* tgt, const Src*, std::streamsize) { return tgt; }
|
||||
};
|
||||
|
||||
template<typename Src, typename Tgt>
|
||||
Tgt* strncpy_if_same(Tgt* tgt, const Src* src, std::streamsize n)
|
||||
{
|
||||
typedef strncpy_if_same_impl<is_same<Src, Tgt>::value> impl;
|
||||
return impl::copy(tgt, src, n);
|
||||
}
|
||||
|
||||
//--------------Definition of conversion_buffer-------------------------------//
|
||||
|
||||
// Buffer and conversion state for reading.
|
||||
template<typename Codecvt, typename Alloc>
|
||||
class conversion_buffer
|
||||
: public buffer<
|
||||
BOOST_DEDUCED_TYPENAME detail::codecvt_extern<Codecvt>::type,
|
||||
Alloc
|
||||
>
|
||||
{
|
||||
public:
|
||||
typedef typename Codecvt::state_type state_type;
|
||||
conversion_buffer()
|
||||
: buffer<
|
||||
BOOST_DEDUCED_TYPENAME detail::codecvt_extern<Codecvt>::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<typename Device, typename Codecvt, typename Alloc>
|
||||
struct code_converter_impl {
|
||||
typedef typename codecvt_extern<Codecvt>::type extern_type;
|
||||
typedef typename category_of<Device>::type device_category;
|
||||
typedef is_convertible<device_category, input> can_read;
|
||||
typedef is_convertible<device_category, output> can_write;
|
||||
typedef is_convertible<device_category, bidirectional> 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<Device>,
|
||||
direct_adapter<Device>,
|
||||
Device
|
||||
>::type device_type;
|
||||
typedef optional< concept_adapter<device_type> > storage_type;
|
||||
typedef is_convertible<device_category, two_sequence> is_double;
|
||||
typedef conversion_buffer<Codecvt, Alloc> buffer_type;
|
||||
|
||||
code_converter_impl() : cvt_(), flags_(0) { }
|
||||
|
||||
~code_converter_impl()
|
||||
{
|
||||
try {
|
||||
if (flags_ & f_open) close();
|
||||
} catch (...) { /* */ }
|
||||
}
|
||||
|
||||
template <class T>
|
||||
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<device_type>(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<Codecvt> 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<typename Device, typename Codecvt, typename Alloc>
|
||||
struct code_converter_base {
|
||||
typedef detail::code_converter_impl<
|
||||
Device, Codecvt, Alloc
|
||||
> impl_type;
|
||||
code_converter_base() : pimpl_(new impl_type) { }
|
||||
shared_ptr<impl_type> pimpl_;
|
||||
};
|
||||
|
||||
template< typename Device,
|
||||
typename Codecvt = detail::default_codecvt,
|
||||
typename Alloc = std::allocator<char> >
|
||||
class code_converter
|
||||
: protected code_converter_base<Device, Codecvt, Alloc>
|
||||
{
|
||||
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>::codecvt_type codecvt_type;
|
||||
typedef typename detail::codecvt_intern<Codecvt>::type intern_type;
|
||||
typedef typename detail::codecvt_extern<Codecvt>::type extern_type;
|
||||
typedef typename detail::codecvt_state<Codecvt>::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<Device>::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<typename T> // 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<typename Device, typename Codevt, typename Alloc>
|
||||
std::streamsize code_converter<Device, Codevt, Alloc>::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<char>::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<std::streamsize>(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<std::streamsize>(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<typename Device, typename Codevt, typename Alloc>
|
||||
std::streamsize code_converter<Device, Codevt, Alloc>::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<std::streamsize>(nint - s);
|
||||
break;
|
||||
case std::codecvt_base::noconv:
|
||||
{
|
||||
std::streamsize amt =
|
||||
std::min<std::streamsize>( 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 <boost/iostreams/detail/config/enable_warnings.hpp> // Borland 5.x
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_CODE_CONVERTER_HPP_INCLUDED
|
260
boost/iostreams/combine.hpp
Normal file
260
boost/iostreams/combine.hpp
Normal file
@ -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 <boost/config.hpp> // NO_STD_LOCALE, DEDUCED_TYPENAME.
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
# include <locale>
|
||||
#endif
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/detail/wrap_unwrap.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
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<typename Source, typename Sink>
|
||||
class combined_device {
|
||||
private:
|
||||
typedef typename category_of<Source>::type in_category;
|
||||
typedef typename category_of<Sink>::type out_category;
|
||||
typedef typename char_type_of<Sink>::type sink_char_type;
|
||||
public:
|
||||
typedef typename char_type_of<Source>::type char_type;
|
||||
struct category
|
||||
: bidirectional,
|
||||
device_tag,
|
||||
closable_tag,
|
||||
localizable_tag
|
||||
{ };
|
||||
BOOST_STATIC_ASSERT(is_device<Source>::value);
|
||||
BOOST_STATIC_ASSERT(is_device<Sink>::value);
|
||||
BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
|
||||
BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::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<typename InputFilter, typename OutputFilter>
|
||||
class combined_filter {
|
||||
private:
|
||||
typedef typename category_of<InputFilter>::type in_category;
|
||||
typedef typename category_of<OutputFilter>::type out_category;
|
||||
typedef typename char_type_of<OutputFilter>::type output_char_type;
|
||||
public:
|
||||
typedef typename char_type_of<InputFilter>::type char_type;
|
||||
struct category
|
||||
: multichar_bidirectional_filter_tag,
|
||||
closable_tag,
|
||||
localizable_tag
|
||||
{ };
|
||||
BOOST_STATIC_ASSERT(is_filter<InputFilter>::value);
|
||||
BOOST_STATIC_ASSERT(is_filter<OutputFilter>::value);
|
||||
BOOST_STATIC_ASSERT((is_convertible<in_category, input>::value));
|
||||
BOOST_STATIC_ASSERT((is_convertible<out_category, output>::value));
|
||||
BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
|
||||
combined_filter(const InputFilter& in, const OutputFilter& out);
|
||||
|
||||
template<typename Source>
|
||||
std::streamsize read(Source& src, char_type* s, std::streamsize n)
|
||||
{ return boost::iostreams::read(in_, src, s, n); }
|
||||
|
||||
template<typename Sink>
|
||||
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
|
||||
{ return boost::iostreams::write(out_, snk, s, n); }
|
||||
|
||||
template<typename Sink>
|
||||
void close(Sink& snk, BOOST_IOS::openmode which)
|
||||
{
|
||||
if (which == BOOST_IOS::in) {
|
||||
if (is_convertible<in_category, dual_use>::value) {
|
||||
iostreams::close(in_, snk, BOOST_IOS::in);
|
||||
} else {
|
||||
detail::close_all(in_, snk);
|
||||
}
|
||||
}
|
||||
if (which == BOOST_IOS::out) {
|
||||
if (is_convertible<out_category, dual_use>::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<typename In, typename Out>
|
||||
struct combination_traits
|
||||
: mpl::if_<
|
||||
is_device<In>,
|
||||
combined_device<
|
||||
typename wrapped_type<In>::type,
|
||||
typename wrapped_type<Out>::type
|
||||
>,
|
||||
combined_filter<
|
||||
typename wrapped_type<In>::type,
|
||||
typename wrapped_type<Out>::type
|
||||
>
|
||||
>
|
||||
{ };
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename In, typename Out>
|
||||
struct combination : detail::combination_traits<In, Out>::type {
|
||||
typedef typename detail::combination_traits<In, Out>::type base_type;
|
||||
typedef typename detail::wrapped_type<In>::type in_type;
|
||||
typedef typename detail::wrapped_type<Out>::type out_type;
|
||||
combination(const in_type& in, const out_type& out)
|
||||
: base_type(in, out) { }
|
||||
};
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Workaround for VC6 ETI bug.
|
||||
template<typename In, typename Out>
|
||||
struct combine_traits {
|
||||
typedef combination<
|
||||
BOOST_DEDUCED_TYPENAME detail::unwrapped_type<In>::type,
|
||||
BOOST_DEDUCED_TYPENAME detail::unwrapped_type<Out>::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 In, typename Out>
|
||||
typename detail::combine_traits<In, Out>::type
|
||||
combine(const In& in, const Out& out)
|
||||
{
|
||||
typedef typename detail::combine_traits<In, Out>::type return_type;
|
||||
return return_type(in, out);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace detail {
|
||||
|
||||
//--------------Implementation of combined_device-----------------------------//
|
||||
|
||||
template<typename Source, typename Sink>
|
||||
inline combined_device<Source, Sink>::combined_device
|
||||
(const Source& src, const Sink& snk)
|
||||
: src_(src), sink_(snk) { }
|
||||
|
||||
template<typename Source, typename Sink>
|
||||
inline std::streamsize
|
||||
combined_device<Source, Sink>::read(char_type* s, std::streamsize n)
|
||||
{ return iostreams::read(src_, s, n); }
|
||||
|
||||
template<typename Source, typename Sink>
|
||||
inline std::streamsize
|
||||
combined_device<Source, Sink>::write(const char_type* s, std::streamsize n)
|
||||
{ return iostreams::write(sink_, s, n); }
|
||||
|
||||
template<typename Source, typename Sink>
|
||||
inline void
|
||||
combined_device<Source, Sink>::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<typename Source, typename Sink>
|
||||
void combined_device<Source, Sink>::imbue(const std::locale& loc)
|
||||
{
|
||||
iostreams::imbue(src_, loc);
|
||||
iostreams::imbue(sink_, loc);
|
||||
}
|
||||
#endif
|
||||
|
||||
//--------------Implementation of filter_pair---------------------------------//
|
||||
|
||||
template<typename InputFilter, typename OutputFilter>
|
||||
inline combined_filter<InputFilter, OutputFilter>::combined_filter
|
||||
(const InputFilter& in, const OutputFilter& out) : in_(in), out_(out)
|
||||
{ }
|
||||
|
||||
#ifndef BOOST_NO_STD_LOCALE
|
||||
template<typename InputFilter, typename OutputFilter>
|
||||
void combined_filter<InputFilter, OutputFilter>::imbue
|
||||
(const std::locale& loc)
|
||||
{
|
||||
iostreams::imbue(in_, loc);
|
||||
iostreams::imbue(out_, loc);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_COMBINE_HPP_INCLUDED
|
493
boost/iostreams/compose.hpp
Normal file
493
boost/iostreams/compose.hpp
Normal file
@ -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 <algorithm> // min.
|
||||
#include <utility> // pair.
|
||||
#include <boost/config.hpp> // DEDUCED_TYPENAME.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/adapter/direct_adapter.hpp>
|
||||
#include <boost/iostreams/detail/call_traits.hpp>
|
||||
#include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
#include <boost/iostreams/detail/functional.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/traits.hpp> // mode_of, is_direct.
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename First,
|
||||
typename Second,
|
||||
typename FirstMode =
|
||||
BOOST_DEDUCED_TYPENAME mode_of<First>::type,
|
||||
typename SecondMode =
|
||||
BOOST_DEDUCED_TYPENAME mode_of<Second>::type >
|
||||
struct composite_mode
|
||||
: select<
|
||||
is_convertible<SecondMode, FirstMode>, FirstMode,
|
||||
is_convertible<FirstMode, SecondMode>, SecondMode,
|
||||
is_convertible<SecondMode, input>, 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<Filter, Device>::type >
|
||||
class composite_device {
|
||||
private:
|
||||
typedef typename detail::param_type<Device>::type param_type;
|
||||
typedef typename mode_of<Filter>::type filter_mode;
|
||||
typedef typename mode_of<Device>::type device_mode;
|
||||
typedef typename
|
||||
iostreams::select< // Disambiguation for Tru64.
|
||||
is_direct<Device>, direct_adapter<Device>,
|
||||
is_std_io<Device>, Device&,
|
||||
else_, Device
|
||||
>::type value_type;
|
||||
BOOST_STATIC_ASSERT(is_filter<Filter>::value);
|
||||
BOOST_STATIC_ASSERT(is_device<Device>::value);
|
||||
public:
|
||||
typedef typename char_type_of<Filter>::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<typename Locale> // Avoid dependency on <locale>
|
||||
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<Filter1, Filter2>::type >
|
||||
class composite_filter {
|
||||
private:
|
||||
typedef reference_wrapper<Filter2> filter_ref;
|
||||
typedef typename mode_of<Filter1>::type first_mode;
|
||||
typedef typename mode_of<Filter2>::type second_mode;
|
||||
|
||||
// A dual-use filter cannot be composed with a read-write filter
|
||||
BOOST_STATIC_ASSERT(
|
||||
!(is_convertible<first_mode, dual_use>::value) ||
|
||||
!(is_convertible<second_mode, input>::value) ||
|
||||
!(is_convertible<second_mode, output>::value) ||
|
||||
(is_convertible<second_mode, dual_use>::value)
|
||||
);
|
||||
BOOST_STATIC_ASSERT(
|
||||
!(is_convertible<second_mode, dual_use>::value) ||
|
||||
!(is_convertible<first_mode, input>::value) ||
|
||||
!(is_convertible<first_mode, output>::value) ||
|
||||
(is_convertible<first_mode, dual_use>::value)
|
||||
);
|
||||
BOOST_STATIC_ASSERT(is_filter<Filter1>::value);
|
||||
BOOST_STATIC_ASSERT(is_filter<Filter2>::value);
|
||||
public:
|
||||
typedef typename char_type_of<Filter1>::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<typename Source>
|
||||
std::streamsize read(Source& src, char_type* s, std::streamsize n)
|
||||
{
|
||||
composite_device<filter_ref, Source> cmp(boost::ref(filter2_), src);
|
||||
return iostreams::read(filter1_, cmp, s, n);
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
|
||||
{
|
||||
composite_device<filter_ref, Sink> cmp(boost::ref(filter2_), snk);
|
||||
return iostreams::write(filter1_, cmp, s, n);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
std::streampos seek( Device& dev, stream_offset off, BOOST_IOS::seekdir way,
|
||||
BOOST_IOS::openmode which =
|
||||
BOOST_IOS::in | BOOST_IOS::out )
|
||||
{
|
||||
composite_device<filter_ref, Device> cmp(boost::ref(filter2_), dev);
|
||||
return iostreams::seek(filter1_, cmp, off, way, which);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
void close(Device& dev)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!is_convertible<category, two_sequence>::value));
|
||||
BOOST_STATIC_ASSERT((!is_convertible<category, dual_use>::value));
|
||||
|
||||
// Create a new device by composing the second filter2_ with dev.
|
||||
composite_device<filter_ref, Device> cmp(boost::ref(filter2_), dev);
|
||||
|
||||
// Close input sequences in reverse order and output sequences in
|
||||
// forward order
|
||||
if (!is_convertible<first_mode, dual_use>::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<second_mode, input>::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<typename Device>
|
||||
void close(Device& dev, BOOST_IOS::openmode which)
|
||||
{
|
||||
BOOST_STATIC_ASSERT(
|
||||
(is_convertible<category, two_sequence>::value) ||
|
||||
(is_convertible<category, dual_use>::value)
|
||||
);
|
||||
|
||||
// Create a new device by composing the second filter2_ with dev.
|
||||
composite_device<filter_ref, Device> cmp(boost::ref(filter2_), dev);
|
||||
|
||||
// Close input sequences in reverse order
|
||||
if ( which == BOOST_IOS::in &&
|
||||
( !is_convertible<first_mode, dual_use>::value ||
|
||||
is_convertible<second_mode, input>::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<first_mode, dual_use>::value ||
|
||||
is_convertible<second_mode, output>::value ) )
|
||||
{
|
||||
detail::execute_all(
|
||||
detail::call_close(filter1_, cmp, BOOST_IOS::out),
|
||||
detail::call_close(filter2_, dev, BOOST_IOS::out)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
bool flush(Device& dev)
|
||||
{
|
||||
composite_device<Filter2, 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<typename Locale> // Avoid dependency on <locale>
|
||||
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<typename Filter, typename FilterOrDevice>
|
||||
struct composite_traits
|
||||
: mpl::if_<
|
||||
is_device<FilterOrDevice>,
|
||||
composite_device<Filter, FilterOrDevice>,
|
||||
composite_filter<Filter, FilterOrDevice>
|
||||
>
|
||||
{ };
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename Filter, typename FilterOrDevice>
|
||||
struct composite : detail::composite_traits<Filter, FilterOrDevice>::type {
|
||||
typedef typename detail::param_type<FilterOrDevice>::type param_type;
|
||||
typedef typename detail::composite_traits<Filter, FilterOrDevice>::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<typename Filter, typename FilterOrDevice>
|
||||
composite<Filter, FilterOrDevice>
|
||||
compose( const Filter& filter, const FilterOrDevice& fod
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
|
||||
{ return composite<Filter, FilterOrDevice>(filter, fod); }
|
||||
|
||||
template<typename Filter, typename Ch, typename Tr>
|
||||
composite< Filter, std::basic_streambuf<Ch, Tr> >
|
||||
compose(const Filter& filter, std::basic_streambuf<Ch, Tr>& sb)
|
||||
{ return composite< Filter, std::basic_streambuf<Ch, Tr> >(filter, sb); }
|
||||
|
||||
template<typename Filter, typename Ch, typename Tr>
|
||||
composite< Filter, std::basic_istream<Ch, Tr> >
|
||||
compose(const Filter& filter, std::basic_istream<Ch, Tr>& is)
|
||||
{ return composite< Filter, std::basic_istream<Ch, Tr> >(filter, is); }
|
||||
|
||||
template<typename Filter, typename Ch, typename Tr>
|
||||
composite< Filter, std::basic_ostream<Ch, Tr> >
|
||||
compose(const Filter& filter, std::basic_ostream<Ch, Tr>& os)
|
||||
{ return composite< Filter, std::basic_ostream<Ch, Tr> >(filter, os); }
|
||||
|
||||
template<typename Filter, typename Ch, typename Tr>
|
||||
composite< Filter, std::basic_iostream<Ch, Tr> >
|
||||
compose(const Filter& filter, std::basic_iostream<Ch, Tr>& io)
|
||||
{ return composite< Filter, std::basic_iostream<Ch, Tr> >(filter, io); }
|
||||
|
||||
# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
|
||||
|
||||
template<typename Filter, typename FilterOrDevice>
|
||||
composite<Filter, FilterOrDevice>
|
||||
compose( const Filter& filter, const FilterOrDevice& fod
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(FilterOrDevice) )
|
||||
{ return composite<Filter, FilterOrDevice>(filter, fod); }
|
||||
|
||||
template<typename Filter>
|
||||
composite<Filter, std::streambuf>
|
||||
compose(const Filter& filter, std::streambuf& sb)
|
||||
{ return composite<Filter, std::streambuf>(filter, sb); }
|
||||
|
||||
template<typename Filter>
|
||||
composite<Filter, std::istream>
|
||||
compose(const Filter& filter, std::istream& is)
|
||||
{ return composite<Filter, std::istream>(filter, is); }
|
||||
|
||||
template<typename Filter>
|
||||
composite<Filter, std::ostream>
|
||||
compose(const Filter& filter, std::ostream& os)
|
||||
{ return composite<Filter, std::ostream>(filter, os); }
|
||||
|
||||
template<typename Filter>
|
||||
composite<Filter, std::iostream>
|
||||
compose(const Filter& filter, std::iostream& io)
|
||||
{ return composite<Filter, std::iostream>(filter, io); }
|
||||
|
||||
# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
|
||||
#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
|
||||
|
||||
template<typename Filter, typename Stream>
|
||||
composite<Filter, Stream>
|
||||
compose(const Filter& flt, const Stream& strm, mpl::true_)
|
||||
{ // Bad overload resolution.
|
||||
return composite<Filter, Stream>(flt, const_cast<Stream&>(strm));
|
||||
}
|
||||
|
||||
template<typename Filter, typename FilterOrDevice>
|
||||
composite<Filter, FilterOrDevice>
|
||||
compose(const Filter& flt, const FilterOrDevice& fod, mpl::false_)
|
||||
{ return composite<Filter, FilterOrDevice>(flt, fod); }
|
||||
|
||||
template<typename Filter, typename FilterOrDevice>
|
||||
composite<Filter, FilterOrDevice>
|
||||
compose( const Filter& flt, const FilterOrDevice& fod
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
|
||||
{ return compose(flt, fod, is_std_io<FilterOrDevice>()); }
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \
|
||||
!defined(__GNUC__) // ---------------------------------------------------//
|
||||
|
||||
template<typename Filter, typename FilterOrDevice>
|
||||
composite<Filter, FilterOrDevice>
|
||||
compose (const Filter& filter, FilterOrDevice& fod)
|
||||
{ return composite<Filter, FilterOrDevice>(filter, fod); }
|
||||
|
||||
# endif // Borland 5.x or GCC //--------------------------------//
|
||||
#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
namespace detail {
|
||||
|
||||
//--------------Implementation of composite_device---------------------------//
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
composite_device<Filter, Device, Mode>::composite_device
|
||||
(const Filter& flt, param_type dev)
|
||||
: filter_(flt), device_(dev)
|
||||
{ }
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
inline std::streamsize composite_device<Filter, Device, Mode>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{ return iostreams::read(filter_, device_, s, n); }
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
inline std::streamsize composite_device<Filter, Device, Mode>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{ return iostreams::write(filter_, device_, s, n); }
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
std::streampos composite_device<Filter, Device, Mode>::seek
|
||||
(stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
|
||||
{ return iostreams::seek(filter_, device_, off, way, which); }
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
void composite_device<Filter, Device, Mode>::close()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!is_convertible<Mode, two_sequence>::value));
|
||||
BOOST_STATIC_ASSERT(
|
||||
!(is_convertible<filter_mode, dual_use>::value) ||
|
||||
!(is_convertible<device_mode, input>::value) ||
|
||||
!(is_convertible<device_mode, output>::value)
|
||||
);
|
||||
|
||||
// Close input sequences in reverse order and output sequences
|
||||
// in forward order
|
||||
if (!is_convertible<filter_mode, dual_use>::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<device_mode, input>::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<typename Filter, typename Device, typename Mode>
|
||||
void composite_device<Filter, Device, Mode>::close(BOOST_IOS::openmode which)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_convertible<Mode, two_sequence>::value));
|
||||
BOOST_STATIC_ASSERT(!(is_convertible<filter_mode, dual_use>::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<typename Filter, typename Device, typename Mode>
|
||||
bool composite_device<Filter, Device, Mode>::flush()
|
||||
{
|
||||
bool r1 = iostreams::flush(filter_, device_);
|
||||
bool r2 = iostreams::flush(device_);
|
||||
return r1 && r2;
|
||||
}
|
||||
|
||||
template<typename Filter, typename Device, typename Mode>
|
||||
std::streamsize
|
||||
composite_device<Filter, Device, Mode>::optimal_buffer_size() const
|
||||
{ return iostreams::optimal_buffer_size(device_); }
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_COMPOSE_HPP_INCLUDED
|
129
boost/iostreams/concepts.hpp
Normal file
129
boost/iostreams/concepts.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/default_arg.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode.
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
//--------------Definitions of helper templates for device concepts-----------//
|
||||
|
||||
template<typename Mode, typename Ch = char>
|
||||
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<Mode, two_sequence>::value));
|
||||
}
|
||||
|
||||
void close(BOOST_IOS::openmode)
|
||||
{
|
||||
using namespace detail;
|
||||
BOOST_STATIC_ASSERT((is_convertible<Mode, two_sequence>::value));
|
||||
}
|
||||
|
||||
template<typename Locale>
|
||||
void imbue(const Locale&) { }
|
||||
};
|
||||
|
||||
template<typename Mode, typename Ch = wchar_t>
|
||||
struct wdevice : device<Mode, Ch> { };
|
||||
|
||||
typedef device<input> source;
|
||||
typedef wdevice<input> wsource;
|
||||
typedef device<output> sink;
|
||||
typedef wdevice<output> wsink;
|
||||
|
||||
//--------------Definitions of helper templates for simple filter concepts----//
|
||||
|
||||
template<typename Mode, typename Ch = char>
|
||||
struct filter {
|
||||
typedef Ch char_type;
|
||||
struct category
|
||||
: Mode,
|
||||
filter_tag,
|
||||
closable_tag,
|
||||
localizable_tag
|
||||
{ };
|
||||
|
||||
template<typename Device>
|
||||
void close(Device&)
|
||||
{
|
||||
using namespace detail;
|
||||
BOOST_STATIC_ASSERT((!is_convertible<Mode, two_sequence>::value));
|
||||
BOOST_STATIC_ASSERT((!is_convertible<Mode, dual_use>::value));
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
void close(Device&, BOOST_IOS::openmode)
|
||||
{
|
||||
using namespace detail;
|
||||
BOOST_STATIC_ASSERT(
|
||||
(is_convertible<Mode, two_sequence>::value) ||
|
||||
(is_convertible<Mode, dual_use>::value)
|
||||
);
|
||||
}
|
||||
|
||||
template<typename Locale>
|
||||
void imbue(const Locale&) { }
|
||||
};
|
||||
|
||||
template<typename Mode, typename Ch = wchar_t>
|
||||
struct wfilter : filter<Mode, Ch> { };
|
||||
|
||||
typedef filter<input> input_filter;
|
||||
typedef wfilter<input> input_wfilter;
|
||||
typedef filter<output> output_filter;
|
||||
typedef wfilter<output> output_wfilter;
|
||||
typedef filter<seekable> seekable_filter;
|
||||
typedef wfilter<seekable> seekable_wfilter;
|
||||
typedef filter<dual_use> dual_use_filter;
|
||||
typedef wfilter<dual_use> dual_use_wfilter;
|
||||
|
||||
//------Definitions of helper templates for multi-character filter cncepts----//
|
||||
|
||||
template<typename Mode, typename Ch = char>
|
||||
struct multichar_filter : filter<Mode, Ch> {
|
||||
struct category : filter<Mode, Ch>::category, multichar_tag { };
|
||||
};
|
||||
|
||||
template<typename Mode, typename Ch = wchar_t>
|
||||
struct multichar_wfilter : multichar_filter<Mode, Ch> { };
|
||||
|
||||
typedef multichar_filter<input> multichar_input_filter;
|
||||
typedef multichar_wfilter<input> multichar_input_wfilter;
|
||||
typedef multichar_filter<output> multichar_output_filter;
|
||||
typedef multichar_wfilter<output> multichar_output_wfilter;
|
||||
typedef multichar_filter<dual_use> multichar_dual_use_filter;
|
||||
typedef multichar_wfilter<dual_use> multichar_dual_use_wfilter;
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_CONCEPTS_HPP_INCLUDED
|
42
boost/iostreams/constants.hpp
Normal file
42
boost/iostreams/constants.hpp
Normal file
@ -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 <boost/iostreams/detail/ios.hpp> // 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
|
248
boost/iostreams/copy.hpp
Normal file
248
boost/iostreams/copy.hpp
Normal file
@ -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 <boost/config.hpp> // Make sure ptrdiff_t is in std.
|
||||
#include <algorithm> // copy, min.
|
||||
#include <cstddef> // ptrdiff_t.
|
||||
#include <utility> // pair.
|
||||
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/chain.hpp>
|
||||
#include <boost/iostreams/constants.hpp>
|
||||
#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
|
||||
#include <boost/iostreams/detail/buffer.hpp>
|
||||
#include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
#include <boost/iostreams/detail/functional.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
|
||||
#include <boost/iostreams/detail/resolve.hpp>
|
||||
#include <boost/iostreams/detail/wrap_unwrap.hpp>
|
||||
#include <boost/iostreams/operations.hpp> // read, write, close.
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
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<typename Source, typename Sink>
|
||||
std::streamsize copy_impl( Source& src, Sink& snk,
|
||||
std::streamsize /* buffer_size */,
|
||||
mpl::true_, mpl::true_ )
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename char_type_of<Source>::type char_type;
|
||||
typedef std::pair<char_type*, char_type*> pair_type;
|
||||
pair_type p1 = iostreams::input_sequence(src);
|
||||
pair_type p2 = iostreams::output_sequence(snk);
|
||||
std::streamsize total =
|
||||
static_cast<std::streamsize>(
|
||||
(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<typename Source, typename Sink>
|
||||
std::streamsize copy_impl( Source& src, Sink& snk,
|
||||
std::streamsize /* buffer_size */,
|
||||
mpl::true_, mpl::false_ )
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename char_type_of<Source>::type char_type;
|
||||
typedef std::pair<char_type*, char_type*> pair_type;
|
||||
pair_type p = iostreams::input_sequence(src);
|
||||
std::streamsize size, total;
|
||||
for ( total = 0, size = static_cast<std::streamsize>(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<typename Source, typename Sink>
|
||||
std::streamsize copy_impl( Source& src, Sink& snk,
|
||||
std::streamsize buffer_size,
|
||||
mpl::false_, mpl::true_ )
|
||||
{
|
||||
typedef typename char_type_of<Source>::type char_type;
|
||||
typedef std::pair<char_type*, char_type*> pair_type;
|
||||
detail::basic_buffer<char_type> 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<std::streamsize>(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<typename Source, typename Sink>
|
||||
std::streamsize copy_impl( Source& src, Sink& snk,
|
||||
std::streamsize buffer_size,
|
||||
mpl::false_, mpl::false_ )
|
||||
{
|
||||
typedef typename char_type_of<Source>::type char_type;
|
||||
detail::basic_buffer<char_type> buf(buffer_size);
|
||||
non_blocking_adapter<Sink> 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<typename Source, typename Sink>
|
||||
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<Source>(), is_direct<Sink>() );
|
||||
}
|
||||
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<typename Source, typename Sink>
|
||||
std::streamsize copy_impl(Source src, Sink snk, std::streamsize buffer_size)
|
||||
{
|
||||
using namespace std;
|
||||
typedef typename char_type_of<Source>::type src_char;
|
||||
typedef typename char_type_of<Sink>::type snk_char;
|
||||
BOOST_STATIC_ASSERT((is_same<src_char, snk_char>::value));
|
||||
return detail::execute_all(
|
||||
copy_operation<Source, Sink>(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<typename Source, typename Sink>
|
||||
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<Source>::type char_type;
|
||||
return detail::copy_impl( detail::resolve<input, char_type>(src),
|
||||
detail::resolve<output, char_type>(snk),
|
||||
buffer_size );
|
||||
}
|
||||
|
||||
// Overload of copy() for the case where the source, but not the sink, is
|
||||
// a standard stream or stream buffer
|
||||
template<typename Source, typename Sink>
|
||||
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<Source>::type char_type;
|
||||
return detail::copy_impl( detail::wrap(src),
|
||||
detail::resolve<output, char_type>(snk),
|
||||
buffer_size );
|
||||
}
|
||||
|
||||
// Overload of copy() for the case where the sink, but not the source, is
|
||||
// a standard stream or stream buffer
|
||||
template<typename Source, typename Sink>
|
||||
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<Source>::type char_type;
|
||||
return detail::copy_impl( detail::resolve<input, char_type>(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<typename Source, typename Sink>
|
||||
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
|
46
boost/iostreams/detail/absolute_path.hpp
Normal file
46
boost/iostreams/detail/absolute_path.hpp
Normal file
@ -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 <string>
|
||||
#include <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
#ifdef BOOST_IOSTREAMS_WINDOWS
|
||||
# include <cctype>
|
||||
#endif
|
||||
#include <boost/iostreams/detail/current_directory.hpp>
|
||||
|
||||
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
|
87
boost/iostreams/detail/access_control.hpp
Normal file
87
boost/iostreams/detail/access_control.hpp
Normal file
@ -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 <boost/iostreams/detail/select.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
struct protected_ { }; // Represents protected inheritance.
|
||||
struct public_ { }; // Represents public inheritance.
|
||||
|
||||
|
||||
namespace detail {
|
||||
|
||||
// Implements protected inheritance.
|
||||
template<typename U>
|
||||
struct prot_ : protected U
|
||||
{
|
||||
prot_() { }
|
||||
template<typename V> prot_(V v) : U(v) { }
|
||||
};
|
||||
|
||||
// Implements public inheritance.
|
||||
template<typename U> struct pub_ : public U {
|
||||
pub_() { }
|
||||
template<typename V> pub_(V v) : U(v) { }
|
||||
};
|
||||
|
||||
//
|
||||
// Used to deduce the base type for the template access_control.
|
||||
//
|
||||
template<typename T, typename Access>
|
||||
struct access_control_base {
|
||||
typedef int bad_access_specifier;
|
||||
typedef typename
|
||||
iostreams::select< // Disambiguation for Tru64
|
||||
::boost::is_same<
|
||||
Access, protected_
|
||||
>, prot_<T>,
|
||||
::boost::is_same<
|
||||
Access, public_
|
||||
>, pub_<T>,
|
||||
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<T, Access>::type >
|
||||
struct access_control : public Base {
|
||||
access_control() { }
|
||||
template<typename U> explicit access_control(U u) : Base(u) { }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_ACCESS_CONTROL_HPP_INCLUDED
|
287
boost/iostreams/detail/adapter/concept_adapter.hpp
Normal file
287
boost/iostreams/detail/adapter/concept_adapter.hpp
Normal file
@ -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 <boost/config.hpp> // SFINAE.
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
|
||||
#include <boost/iostreams/detail/call_traits.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/dispatch.hpp>
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/detail/streambuf.hpp> // pubsync.
|
||||
#include <boost/iostreams/detail/config/unreachable_return.hpp>
|
||||
#include <boost/iostreams/device/null.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Category> struct device_wrapper_impl;
|
||||
template<typename Category> struct flt_wrapper_impl;
|
||||
|
||||
template<typename T>
|
||||
class concept_adapter {
|
||||
private:
|
||||
typedef typename detail::value_type<T>::type value_type;
|
||||
typedef typename dispatch<T, input, output>::type input_tag;
|
||||
typedef typename dispatch<T, output, input>::type output_tag;
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
is_device<T>,
|
||||
device_wrapper_impl<input_tag>,
|
||||
flt_wrapper_impl<input_tag>
|
||||
>::type input_impl;
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
is_device<T>,
|
||||
device_wrapper_impl<output_tag>,
|
||||
flt_wrapper_impl<output_tag>
|
||||
>::type output_impl;
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
is_device<T>,
|
||||
device_wrapper_impl<any_tag>,
|
||||
flt_wrapper_impl<any_tag>
|
||||
>::type any_impl;
|
||||
public:
|
||||
typedef typename char_type_of<T>::type char_type;
|
||||
typedef typename category_of<T>::type category;
|
||||
|
||||
explicit concept_adapter(const reference_wrapper<T>& ref) : t_(ref.get())
|
||||
{ BOOST_STATIC_ASSERT(is_std_io<T>::value); }
|
||||
explicit concept_adapter(const T& t) : t_(t)
|
||||
{ BOOST_STATIC_ASSERT(!is_std_io<T>::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<char_type>*) 0); }
|
||||
|
||||
template<typename Source>
|
||||
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<char_type>*) 0); }
|
||||
|
||||
template<typename Sink>
|
||||
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<char_type, seekable>*) 0);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
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<char_type, seekable>*) 0); }
|
||||
|
||||
template<typename Device>
|
||||
void close(BOOST_IOS::openmode which, Device* dev)
|
||||
{ any_impl::close(t_, dev, which); }
|
||||
|
||||
template<typename Device>
|
||||
bool flush( Device* dev )
|
||||
{
|
||||
bool result = any_impl::flush(t_, dev);
|
||||
if (dev && dev->BOOST_IOSTREAMS_PUBSYNC() == -1)
|
||||
result = false;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Locale> // Avoid dependency on <locale>
|
||||
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<any_tag> {
|
||||
template<typename Device, typename Dummy>
|
||||
static std::streampos
|
||||
seek( Device& dev, Dummy*, stream_offset off,
|
||||
BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
|
||||
{
|
||||
typedef typename category_of<Device>::type category;
|
||||
return seek(dev, off, way, which, category());
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
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<typename Device>
|
||||
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<typename Device, typename Dummy>
|
||||
static void close(Device& dev, Dummy*, BOOST_IOS::openmode which)
|
||||
{ iostreams::close(dev, which); }
|
||||
|
||||
template<typename Device, typename Dummy>
|
||||
static bool flush(Device& dev, Dummy*)
|
||||
{ return iostreams::flush(dev); }
|
||||
};
|
||||
|
||||
|
||||
template<>
|
||||
struct device_wrapper_impl<input> : device_wrapper_impl<any_tag> {
|
||||
template<typename Device, typename Dummy>
|
||||
static std::streamsize
|
||||
read( Device& dev, Dummy*, typename char_type_of<Device>::type* s,
|
||||
std::streamsize n )
|
||||
{ return iostreams::read(dev, s, n); }
|
||||
|
||||
template<typename Device, typename Dummy>
|
||||
static std::streamsize
|
||||
write( Device&, Dummy*, const typename char_type_of<Device>::type*,
|
||||
std::streamsize )
|
||||
{ boost::throw_exception(cant_write());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct device_wrapper_impl<output> {
|
||||
template<typename Device, typename Dummy>
|
||||
static std::streamsize
|
||||
read(Device&, Dummy*, typename char_type_of<Device>::type*, std::streamsize)
|
||||
{ boost::throw_exception(cant_read());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
|
||||
template<typename Device, typename Dummy>
|
||||
static std::streamsize
|
||||
write( Device& dev, Dummy*, const typename char_type_of<Device>::type* s,
|
||||
std::streamsize n )
|
||||
{ return iostreams::write(dev, s, n); }
|
||||
};
|
||||
|
||||
//------------------Specializations of flt_wrapper_impl--------------------//
|
||||
|
||||
template<>
|
||||
struct flt_wrapper_impl<any_tag> {
|
||||
template<typename Filter, typename Device>
|
||||
static std::streampos
|
||||
seek( Filter& f, Device* dev, stream_offset off,
|
||||
BOOST_IOS::seekdir way, BOOST_IOS::openmode which )
|
||||
{
|
||||
typedef typename category_of<Filter>::type category;
|
||||
return seek(f, dev, off, way, which, category());
|
||||
}
|
||||
|
||||
template<typename Filter, typename Device>
|
||||
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<typename Filter, typename Device>
|
||||
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<Filter>::type category;
|
||||
return seek(f, dev, off, way, which, tag, category());
|
||||
}
|
||||
|
||||
template<typename Filter, typename Device>
|
||||
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<typename Filter, typename Device>
|
||||
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<typename Filter, typename Device>
|
||||
static void close(Filter& f, Device* dev, BOOST_IOS::openmode which)
|
||||
{ iostreams::close(f, *dev, which); }
|
||||
|
||||
template<typename Filter, typename Device>
|
||||
static bool flush(Filter& f, Device* dev)
|
||||
{ return iostreams::flush(f, *dev); }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct flt_wrapper_impl<input> {
|
||||
template<typename Filter, typename Source>
|
||||
static std::streamsize
|
||||
read( Filter& f, Source* src, typename char_type_of<Filter>::type* s,
|
||||
std::streamsize n )
|
||||
{ return iostreams::read(f, *src, s, n); }
|
||||
|
||||
template<typename Filter, typename Sink>
|
||||
static std::streamsize
|
||||
write( Filter&, Sink*, const typename char_type_of<Filter>::type*,
|
||||
std::streamsize )
|
||||
{ boost::throw_exception(cant_write());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
};
|
||||
|
||||
template<>
|
||||
struct flt_wrapper_impl<output> {
|
||||
template<typename Filter, typename Source>
|
||||
static std::streamsize
|
||||
read(Filter&, Source*, typename char_type_of<Filter>::type*,std::streamsize)
|
||||
{ boost::throw_exception(cant_read());
|
||||
BOOST_IOSTREAMS_UNREACHABLE_RETURN(0) }
|
||||
|
||||
template<typename Filter, typename Sink>
|
||||
static std::streamsize
|
||||
write( Filter& f, Sink* snk, const typename char_type_of<Filter>::type* s,
|
||||
std::streamsize n )
|
||||
{ return iostreams::write(f, *snk, s, n); }
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONCEPT_ADAPTER_HPP_INCLUDED
|
67
boost/iostreams/detail/adapter/device_adapter.hpp
Normal file
67
boost/iostreams/detail/adapter/device_adapter.hpp
Normal file
@ -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 <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/call_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
class device_adapter {
|
||||
private:
|
||||
typedef typename detail::value_type<T>::type value_type;
|
||||
typedef typename detail::param_type<T>::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<typename Locale> // Avoid dependency on <locale>
|
||||
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
|
282
boost/iostreams/detail/adapter/direct_adapter.hpp
Normal file
282
boost/iostreams/detail/adapter/direct_adapter.hpp
Normal file
@ -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 <boost/config.hpp> // SFINAE, MSVC, put ptrdiff_t in std.
|
||||
#include <algorithm> // copy, min.
|
||||
#include <cstddef> // ptrdiff_t.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/config/limits.hpp> // forwarding.
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp> // locale.
|
||||
#include <boost/iostreams/detail/double_object.hpp>
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
|
||||
#include <boost/iostreams/traits.hpp> // mode_of, is_direct.
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/or.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // VC7.1
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
//------------------Definition of direct_adapter_base-------------------------//
|
||||
|
||||
// Put all initialization in base class to faciliate forwarding.
|
||||
template<typename Direct>
|
||||
class direct_adapter_base {
|
||||
public:
|
||||
typedef typename char_type_of<Direct>::type char_type;
|
||||
typedef typename mode_of<Direct>::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<category, two_sequence> 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<pointers, is_double> ptrs_;
|
||||
Direct d_;
|
||||
};
|
||||
|
||||
template<typename Direct>
|
||||
class direct_adapter : private direct_adapter_base<Direct> {
|
||||
private:
|
||||
typedef direct_adapter_base<Direct> 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<typename U>
|
||||
struct is_direct
|
||||
: mpl::or_<
|
||||
is_same<U, direct_adapter<Direct> >,
|
||||
is_same<U, Direct>
|
||||
>
|
||||
{ };
|
||||
template<typename U>
|
||||
direct_adapter(const U& u)
|
||||
: base_type(forward(u, is_direct<U>()))
|
||||
{ }
|
||||
# define BOOST_PP_LOCAL_LIMITS (2, BOOST_IOSTREAMS_MAX_FORWARDING_ARITY)
|
||||
#endif
|
||||
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<BOOST_PP_ENUM_PARAMS(n, typename P)> \
|
||||
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<typename U>
|
||||
static Direct forward(const U& u, mpl::true_) { return u; }
|
||||
template<typename U>
|
||||
static Direct forward(const U& u, mpl::false_) { return Direct(u); }
|
||||
#endif
|
||||
};
|
||||
|
||||
//--------------Definition of wrap_direct and unwrap_direct-------------------//
|
||||
|
||||
template<typename Device>
|
||||
struct wrap_direct_traits
|
||||
: mpl::if_<
|
||||
is_direct<Device>,
|
||||
direct_adapter<Device>,
|
||||
Device
|
||||
>
|
||||
{ };
|
||||
|
||||
template<typename Device>
|
||||
typename wrap_direct_traits<Device>::type
|
||||
inline wrap_direct(Device dev)
|
||||
{
|
||||
typedef typename wrap_direct_traits<Device>::type type;
|
||||
return type(dev);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
inline Device& unwrap_direct(Device& d) { return d; }
|
||||
|
||||
template<typename Device>
|
||||
inline Device& unwrap_direct(direct_adapter<Device>& d) { return *d; }
|
||||
|
||||
//--------------Implementation of direct_adapter_base-------------------------//
|
||||
|
||||
template<typename Direct>
|
||||
direct_adapter_base<Direct>::direct_adapter_base(const Direct& d) : d_(d)
|
||||
{
|
||||
init_input(is_convertible<category, input>());
|
||||
init_output(is_convertible<category, output>());
|
||||
}
|
||||
|
||||
template<typename Direct>
|
||||
void direct_adapter_base<Direct>::init_input(mpl::true_)
|
||||
{
|
||||
std::pair<char_type*, char_type*> seq = iostreams::input_sequence(d_);
|
||||
ptrs_.first().beg = seq.first;
|
||||
ptrs_.first().ptr = seq.first;
|
||||
ptrs_.first().end = seq.second;
|
||||
}
|
||||
|
||||
template<typename Direct>
|
||||
void direct_adapter_base<Direct>::init_output(mpl::true_)
|
||||
{
|
||||
std::pair<char_type*, char_type*> 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<typename Direct>
|
||||
inline std::streamsize direct_adapter<Direct>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{
|
||||
using namespace std;
|
||||
pointers& get = ptrs_.first();
|
||||
std::streamsize avail =
|
||||
static_cast<std::streamsize>(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<typename Direct>
|
||||
inline std::streamsize direct_adapter<Direct>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{
|
||||
using namespace std;
|
||||
pointers& put = ptrs_.second();
|
||||
if (n > static_cast<std::streamsize>(put.end - put.ptr))
|
||||
boost::throw_exception(write_area_exhausted());
|
||||
std::copy(s, s + n, put.ptr);
|
||||
put.ptr += n;
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename Direct>
|
||||
inline std::streampos direct_adapter<Direct>::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<typename Direct>
|
||||
void direct_adapter<Direct>::close()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((!is_convertible<category, two_sequence>::value));
|
||||
detail::close_all(d_);
|
||||
}
|
||||
|
||||
template<typename Direct>
|
||||
void direct_adapter<Direct>::close(BOOST_IOS::openmode which)
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_convertible<category, two_sequence>::value));
|
||||
boost::iostreams::close(d_, which);
|
||||
}
|
||||
|
||||
#ifndef BOOST_IOSTREAMS_NO_LOCALE
|
||||
template<typename Direct>
|
||||
void direct_adapter<Direct>::imbue(const std::locale& loc)
|
||||
{ boost::iostreams::imbue(d_, loc); }
|
||||
#endif
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_ADAPTER_HPP_INCLUDED
|
69
boost/iostreams/detail/adapter/filter_adapter.hpp
Normal file
69
boost/iostreams/detail/adapter/filter_adapter.hpp
Normal file
@ -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 <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/call_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
class filter_adapter {
|
||||
private:
|
||||
typedef typename detail::value_type<T>::type value_type;
|
||||
typedef typename detail::param_type<T>::type param_type;
|
||||
public:
|
||||
explicit filter_adapter(param_type t) : t_(t) { }
|
||||
T& component() { return t_; }
|
||||
|
||||
template<typename Device>
|
||||
void close(Device& dev)
|
||||
{
|
||||
detail::close_all(t_, dev);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
void close(Device& dev, BOOST_IOS::openmode which)
|
||||
{
|
||||
iostreams::close(t_, dev, which);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
void flush(Device& dev)
|
||||
{
|
||||
return iostreams::flush(t_, dev);
|
||||
}
|
||||
|
||||
template<typename Locale> // Avoid dependency on <locale>
|
||||
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
|
117
boost/iostreams/detail/adapter/mode_adapter.hpp
Normal file
117
boost/iostreams/detail/adapter/mode_adapter.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Mode, typename T>
|
||||
class mode_adapter {
|
||||
private:
|
||||
struct empty_base { };
|
||||
public:
|
||||
typedef typename wrapped_type<T>::type component_type;
|
||||
typedef typename char_type_of<T>::type char_type;
|
||||
struct category
|
||||
: Mode,
|
||||
device_tag,
|
||||
mpl::if_<is_filter<T>, filter_tag, device_tag>,
|
||||
mpl::if_<is_filter<T>, 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<typename Source>
|
||||
std::streamsize read(Source& src, char_type* s, std::streamsize n)
|
||||
{ return iostreams::read(t_, src, s, n); }
|
||||
|
||||
template<typename Sink>
|
||||
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
|
||||
{ return iostreams::write(t_, snk, s, n); }
|
||||
|
||||
template<typename Device>
|
||||
std::streampos seek(Device& dev, stream_offset off, BOOST_IOS::seekdir way)
|
||||
{ return iostreams::seek(t_, dev, off, way); }
|
||||
|
||||
template<typename Device>
|
||||
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<typename Device>
|
||||
void close(Device& dev)
|
||||
{ detail::close_all(t_, dev); }
|
||||
|
||||
template<typename Device>
|
||||
void close(Device& dev, BOOST_IOS::openmode which)
|
||||
{ iostreams::close(t_, dev, which); }
|
||||
|
||||
template<typename Locale>
|
||||
void imbue(const Locale& loc)
|
||||
{ iostreams::imbue(t_, loc); }
|
||||
private:
|
||||
component_type t_;
|
||||
};
|
||||
|
||||
//------------------Implementation of mode_adapter----------------------------//
|
||||
|
||||
template<typename Mode, typename T>
|
||||
std::streamsize mode_adapter<Mode, T>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{ return boost::iostreams::read(t_, s, n); }
|
||||
|
||||
template<typename Mode, typename T>
|
||||
std::streamsize mode_adapter<Mode, T>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{ return boost::iostreams::write(t_, s, n); }
|
||||
|
||||
template<typename Mode, typename T>
|
||||
std::streampos mode_adapter<Mode, T>::seek
|
||||
(stream_offset off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
|
||||
{ return boost::iostreams::seek(t_, off, way, which); }
|
||||
|
||||
template<typename Mode, typename T>
|
||||
void mode_adapter<Mode, T>::close()
|
||||
{ detail::close_all(t_); }
|
||||
|
||||
template<typename Mode, typename T>
|
||||
void mode_adapter<Mode, T>::close(BOOST_IOS::openmode which)
|
||||
{ iostreams::close(t_, which); }
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_MODE_ADAPTER_HPP_INCLUDED //-----//
|
62
boost/iostreams/detail/adapter/non_blocking_adapter.hpp
Normal file
62
boost/iostreams/detail/adapter/non_blocking_adapter.hpp
Normal file
@ -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 <boost/iostreams/detail/ios.hpp> // streamsize, seekdir, openmode.
|
||||
#include <boost/iostreams/read.hpp>
|
||||
#include <boost/iostreams/seek.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/write.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template<typename Device>
|
||||
class non_blocking_adapter {
|
||||
public:
|
||||
typedef typename char_type_of<Device>::type char_type;
|
||||
struct category
|
||||
: mode_of<Device>::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
|
41
boost/iostreams/detail/adapter/output_iterator_adapter.hpp
Normal file
41
boost/iostreams/detail/adapter/output_iterator_adapter.hpp
Normal file
@ -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 <algorithm> // copy.
|
||||
#include <iosfwd> // streamsize.
|
||||
#include <boost/iostreams/categories.hpp> // tags.
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Mode, typename Ch, typename OutIt>
|
||||
class output_iterator_adapter {
|
||||
public:
|
||||
BOOST_STATIC_ASSERT((is_convertible<Mode, output>::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 //-----//
|
187
boost/iostreams/detail/adapter/range_adapter.hpp
Normal file
187
boost/iostreams/detail/adapter/range_adapter.hpp
Normal file
@ -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 <algorithm> // min.
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstddef> // ptrdiff_t.
|
||||
#include <iosfwd> // streamsize, streamoff.
|
||||
#include <iterator> // iterator_traits.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/core/enable_if.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// Used for simulated tag dispatch.
|
||||
template<typename Traversal> 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<typename Mode, typename Range>
|
||||
class range_adapter {
|
||||
private:
|
||||
typedef typename Range::iterator iterator;
|
||||
typedef std::iterator_traits<iterator> 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<tag> 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<typename Mode, typename Range>
|
||||
range_adapter<Mode, Range>::range_adapter(const Range& rng)
|
||||
: first_(rng.begin()), cur_(rng.begin()), last_(rng.end()) { }
|
||||
|
||||
template<typename Mode, typename Range>
|
||||
range_adapter<Mode, Range>::range_adapter(iterator first, iterator last)
|
||||
: first_(first), cur_(first), last_(last) { }
|
||||
|
||||
template<typename Mode, typename Range>
|
||||
inline std::streamsize range_adapter<Mode, Range>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{ return impl::read(cur_, last_, s, n); }
|
||||
|
||||
template<typename Mode, typename Range>
|
||||
inline std::streamsize range_adapter<Mode, Range>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{ return impl::write(cur_, last_, s, n); }
|
||||
|
||||
|
||||
template<typename Mode, typename Range>
|
||||
std::streampos range_adapter<Mode, Range>::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<std::forward_iterator_tag> {
|
||||
template<typename Iter, typename Ch>
|
||||
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<typename Iter, typename Ch>
|
||||
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<std::random_access_iterator_tag> {
|
||||
template<typename Iter, typename Ch>
|
||||
static std::streamsize read
|
||||
(Iter& cur, Iter& last, Ch* s,std::streamsize n)
|
||||
{
|
||||
std::streamsize result =
|
||||
(std::min)(static_cast<std::streamsize>(last - cur), n);
|
||||
if (result)
|
||||
std::copy(cur, cur + result, s);
|
||||
cur += result;
|
||||
return result != 0 ? result : -1;
|
||||
}
|
||||
|
||||
template<typename Iter, typename Ch>
|
||||
static std::streamsize write
|
||||
(Iter& cur, Iter& last, const Ch* s, std::streamsize n)
|
||||
{
|
||||
std::streamsize count =
|
||||
(std::min)(static_cast<std::streamsize>(last - cur), n);
|
||||
std::copy(s, s + count, cur);
|
||||
cur += count;
|
||||
if (count < n)
|
||||
boost::throw_exception(write_area_exhausted());
|
||||
return n;
|
||||
}
|
||||
|
||||
template<typename Iter>
|
||||
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 <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_RANGE_ADAPTER_HPP_INCLUDED //---------------//
|
49
boost/iostreams/detail/add_facet.hpp
Normal file
49
boost/iostreams/detail/add_facet.hpp
Normal file
@ -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 <boost/archive/add_facet.hpp>
|
||||
|
||||
#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/config.hpp> // BOOST_DINKUMWARE_STDLIB.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
//------------------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<class Facet>
|
||||
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
|
49
boost/iostreams/detail/bool_trait_def.hpp
Normal file
49
boost/iostreams/detail/bool_trait_def.hpp
Normal file
@ -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/config.hpp> // BOOST_STATIC_CONSTANT.
|
||||
#include <boost/iostreams/detail/template_params.hpp>
|
||||
#include <boost/mpl/aux_/lambda_support.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/type_traits/detail/yes_no_type.hpp>
|
||||
|
||||
//
|
||||
// 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<typename T> \
|
||||
struct impl { \
|
||||
BOOST_STATIC_CONSTANT(bool, value = \
|
||||
(sizeof(BOOST_IOSTREAMS_TRAIT_NAMESPACE(trait) \
|
||||
helper(static_cast<T*>(0))) == \
|
||||
sizeof(type_traits::yes_type))); \
|
||||
}; \
|
||||
} \
|
||||
template<typename T> \
|
||||
struct trait \
|
||||
: mpl::bool_<BOOST_PP_CAT(trait, _impl_)::impl<T>::value> \
|
||||
{ BOOST_MPL_AUX_LAMBDA_SUPPORT(1, trait, (T)) }; \
|
||||
/**/
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BOOL_TRAIT_DEF_HPP_INCLUDED
|
@ -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/config.hpp> // BOOST_STATIC_CONSANT.
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Device, typename U>
|
||||
struct forward_impl {
|
||||
BOOST_STATIC_CONSTANT(bool, value =
|
||||
( !is_same< U, Device >::value &&
|
||||
!is_same< U, reference_wrapper<Device> >::value ));
|
||||
};
|
||||
|
||||
template<typename Device, typename U>
|
||||
struct forward
|
||||
: mpl::bool_<forward_impl<Device, U>::value>
|
||||
{ };
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BROKEN_OVERLOAD_RESOLUTION_HPP_INCLUDED
|
184
boost/iostreams/detail/broken_overload_resolution/stream.hpp
Normal file
184
boost/iostreams/detail/broken_overload_resolution/stream.hpp
Normal file
@ -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 <boost/iostreams/detail/broken_overload_resolution/forward.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template< typename Device,
|
||||
typename Tr =
|
||||
BOOST_IOSTREAMS_CHAR_TRAITS(
|
||||
BOOST_DEDUCED_TYPENAME char_type_of<Device>::type
|
||||
),
|
||||
typename Alloc =
|
||||
std::allocator<
|
||||
BOOST_DEDUCED_TYPENAME char_type_of<Device>::type
|
||||
> >
|
||||
struct stream : detail::stream_base<Device, Tr, Alloc> {
|
||||
public:
|
||||
typedef typename char_type_of<Device>::type char_type;
|
||||
struct category
|
||||
: mode_of<Device>::type,
|
||||
closable_tag,
|
||||
detail::stream_traits<Device, Tr>::stream_tag
|
||||
{ };
|
||||
BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
|
||||
private:
|
||||
typedef typename
|
||||
detail::stream_traits<
|
||||
Device, Tr
|
||||
>::stream_type stream_type;
|
||||
public:
|
||||
stream() { }
|
||||
template<typename U0>
|
||||
stream(const U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
stream(const U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
stream(const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1, u2);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
stream(U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
stream(U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
stream(U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1, u2);
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0>
|
||||
void open(const U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open(const U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open(const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1, u2);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open(U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open(U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open(U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<Device, U0>(), 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<typename U0>
|
||||
void open_impl(mpl::false_, const U0& u0)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(u0);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::false_, U0& u0)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(detail::wrap(u0));
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::true_, const U0& u0)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(Device(const_cast<U0&>(u0)));
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::true_, U0& u0)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(Device(u0));
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0, typename U1>
|
||||
void open_impl(mpl::false_, const U0& u0, const U1& u1)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open_impl(mpl::true_, const U0& u0, const U1& u1)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(Device(const_cast<U0&>(u0), u1));
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0, typename U1>
|
||||
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<typename U0, typename U1, typename U2>
|
||||
void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(u0, u1, u2);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
this->clear();
|
||||
this->member.open(Device(const_cast<U0&>(u0), u1, u2));
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0, typename U1, typename U2>
|
||||
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
|
@ -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 <boost/iostreams/detail/broken_overload_resolution/forward.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template< typename T,
|
||||
typename Tr =
|
||||
BOOST_IOSTREAMS_CHAR_TRAITS(
|
||||
BOOST_DEDUCED_TYPENAME char_type_of<T>::type
|
||||
),
|
||||
typename Alloc =
|
||||
std::allocator<
|
||||
BOOST_DEDUCED_TYPENAME char_type_of<T>::type
|
||||
>,
|
||||
typename Mode = BOOST_DEDUCED_TYPENAME mode_of<T>::type >
|
||||
class stream_buffer
|
||||
: public detail::stream_buffer_traits<T, Tr, Alloc, Mode>::type
|
||||
{
|
||||
private:
|
||||
BOOST_STATIC_ASSERT((
|
||||
is_convertible<
|
||||
BOOST_DEDUCED_TYPENAME iostreams::category_of<T>::type, Mode
|
||||
>::value
|
||||
));
|
||||
typedef typename
|
||||
detail::stream_buffer_traits<
|
||||
T, Tr, Alloc, Mode
|
||||
>::type base_type;
|
||||
public:
|
||||
typedef typename char_type_of<T>::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<typename U0>
|
||||
stream_buffer(const U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
stream_buffer(const U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
stream_buffer(const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1, u2);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
stream_buffer(U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
stream_buffer(U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
stream_buffer(U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1, u2);
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0>
|
||||
void open(const U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open(const U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open(const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1, u2);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open(U0& u0)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open(U0& u0, const U1& u1)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open(U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
open_impl(detail::forward<T, U0>(), u0, u1, u2);
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
T& operator*() { return *this->component(); }
|
||||
T* operator->() { return this->component(); }
|
||||
private:
|
||||
template<typename U0>
|
||||
void open_impl(mpl::false_, const U0& u0)
|
||||
{
|
||||
base_type::open(const_cast<U0&>(u0), -1, -1);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::false_, U0& u0)
|
||||
{
|
||||
base_type::open(detail::wrap(u0), -1, -1);
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::true_, const U0& u0)
|
||||
{
|
||||
base_type::open(T(const_cast<U0&>(u0)), -1, -1);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0>
|
||||
void open_impl(mpl::true_, U0& u0)
|
||||
{
|
||||
base_type::open(T(u0), -1, -1);
|
||||
}
|
||||
#endif // !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------//
|
||||
template<typename U0, typename U1>
|
||||
void open_impl(mpl::false_, const U0& u0, const U1& u1)
|
||||
{
|
||||
base_type::open(u0, u1, -1);
|
||||
}
|
||||
template<typename U0, typename U1>
|
||||
void open_impl(mpl::true_, const U0& u0, const U1& u1)
|
||||
{
|
||||
base_type::open(T(const_cast<U0&>(u0), u1), -1, -1);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0, typename U1>
|
||||
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<typename U0, typename U1, typename U2>
|
||||
void open_impl(mpl::false_, const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
base_type::open(u0, u1, u2);
|
||||
}
|
||||
template<typename U0, typename U1, typename U2>
|
||||
void open_impl(mpl::true_, const U0& u0, const U1& u1, const U2& u2)
|
||||
{
|
||||
base_type::open(T(const_cast<U0&>(u0), u1, u2), -1, -1);
|
||||
}
|
||||
#if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
|
||||
template<typename U0, typename U1, typename U2>
|
||||
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
|
229
boost/iostreams/detail/buffer.hpp
Normal file
229
boost/iostreams/detail/buffer.hpp
Normal file
@ -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 <algorithm> // swap.
|
||||
#include <memory> // allocator.
|
||||
#include <boost/config.hpp> // member templates.
|
||||
#include <boost/iostreams/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // streamsize.
|
||||
#include <boost/iostreams/read.hpp>
|
||||
#include <boost/iostreams/traits.hpp> // int_type_of.
|
||||
#include <boost/iostreams/checked_operations.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
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<Ch> >
|
||||
class basic_buffer {
|
||||
private:
|
||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename Alloc::template rebind<Ch>::other allocator_type;
|
||||
#else
|
||||
typedef typename std::allocator_traits<Alloc>::template rebind_alloc<Ch> allocator_type;
|
||||
typedef std::allocator_traits<allocator_type> allocator_traits;
|
||||
#endif
|
||||
#else
|
||||
typedef std::allocator<Ch> 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<typename Ch, typename Alloc>
|
||||
void swap(basic_buffer<Ch, Alloc>& lhs, basic_buffer<Ch, Alloc>& rhs)
|
||||
{ lhs.swap(rhs); }
|
||||
|
||||
//
|
||||
// Template name: buffer
|
||||
// Description: Character buffer with two pointers accessible via ptr() and
|
||||
// eptr().
|
||||
// Template parameters:
|
||||
// Ch - A character type.
|
||||
//
|
||||
template< typename Ch,
|
||||
typename Alloc = std::allocator<Ch> >
|
||||
class buffer : public basic_buffer<Ch, Alloc> {
|
||||
private:
|
||||
typedef basic_buffer<Ch, Alloc> base;
|
||||
public:
|
||||
typedef iostreams::char_traits<Ch> traits_type;
|
||||
using base::resize;
|
||||
using base::data;
|
||||
using base::size;
|
||||
typedef Ch* const const_pointer;
|
||||
buffer(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 Source>
|
||||
typename int_type_of<Source>::type fill(Source& src)
|
||||
{
|
||||
using namespace std;
|
||||
std::streamsize keep;
|
||||
if ((keep = static_cast<std::streamsize>(eptr_ - ptr_)) > 0)
|
||||
traits_type::move(
|
||||
this->data(),
|
||||
ptr_,
|
||||
static_cast<size_t>(keep)
|
||||
);
|
||||
set(0, keep);
|
||||
std::streamsize result =
|
||||
iostreams::read(src, this->data() + keep, this->size() - keep);
|
||||
if (result != -1)
|
||||
this->set(0, keep + result);
|
||||
return result == -1 ?
|
||||
traits_type::eof() :
|
||||
result == 0 ?
|
||||
traits_type::would_block() :
|
||||
traits_type::good();
|
||||
|
||||
}
|
||||
|
||||
// Returns true if one or more characters were written.
|
||||
template<typename Sink>
|
||||
bool flush(Sink& dest)
|
||||
{
|
||||
using namespace std;
|
||||
std::streamsize amt = static_cast<std::streamsize>(eptr_ - ptr_);
|
||||
std::streamsize result = iostreams::write_if(dest, ptr_, amt);
|
||||
if (result < amt) {
|
||||
traits_type::move( this->data(),
|
||||
ptr_ + static_cast<size_t>(result),
|
||||
static_cast<size_t>(amt - result) );
|
||||
}
|
||||
this->set(0, amt - result);
|
||||
return result != 0;
|
||||
}
|
||||
private:
|
||||
Ch *ptr_, *eptr_;
|
||||
};
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
void swap(buffer<Ch, Alloc>& lhs, buffer<Ch, Alloc>& rhs)
|
||||
{ lhs.swap(rhs); }
|
||||
|
||||
//--------------Implementation of basic_buffer--------------------------------//
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
basic_buffer<Ch, Alloc>::basic_buffer() : buf_(0), size_(0) { }
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
inline Ch* basic_buffer<Ch, Alloc>::allocate(std::streamsize buffer_size)
|
||||
{
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
|
||||
return static_cast<Ch*>(allocator_type().allocate(
|
||||
static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(buffer_size), 0));
|
||||
#else
|
||||
allocator_type alloc;
|
||||
return static_cast<Ch*>(allocator_traits::allocate(alloc,
|
||||
static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(buffer_size)));
|
||||
#endif
|
||||
}
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
basic_buffer<Ch, Alloc>::basic_buffer(std::streamsize buffer_size)
|
||||
: buf_(allocate(buffer_size)),
|
||||
size_(buffer_size) // Cast for SunPro 5.3.
|
||||
{ }
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
inline basic_buffer<Ch, Alloc>::~basic_buffer()
|
||||
{
|
||||
if (buf_) {
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR) || defined(BOOST_NO_STD_ALLOCATOR)
|
||||
allocator_type().deallocate(buf_,
|
||||
static_cast<BOOST_DEDUCED_TYPENAME Alloc::size_type>(size_));
|
||||
#else
|
||||
allocator_type alloc;
|
||||
allocator_traits::deallocate(alloc, buf_,
|
||||
static_cast<BOOST_DEDUCED_TYPENAME allocator_traits::size_type>(size_));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
inline void basic_buffer<Ch, Alloc>::resize(std::streamsize buffer_size)
|
||||
{
|
||||
if (size_ != buffer_size) {
|
||||
basic_buffer<Ch, Alloc> temp(buffer_size);
|
||||
std::swap(size_, temp.size_);
|
||||
std::swap(buf_, temp.buf_);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
void basic_buffer<Ch, Alloc>::swap(basic_buffer& rhs)
|
||||
{
|
||||
std::swap(buf_, rhs.buf_);
|
||||
std::swap(size_, rhs.size_);
|
||||
}
|
||||
|
||||
//--------------Implementation of buffer--------------------------------------//
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
buffer<Ch, Alloc>::buffer(std::streamsize buffer_size)
|
||||
: basic_buffer<Ch, Alloc>(buffer_size), ptr_(data()), eptr_(data() + buffer_size) { }
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
inline void buffer<Ch, Alloc>::set(std::streamsize ptr, std::streamsize end)
|
||||
{
|
||||
ptr_ = data() + ptr;
|
||||
eptr_ = data() + end;
|
||||
}
|
||||
|
||||
template<typename Ch, typename Alloc>
|
||||
inline void buffer<Ch, Alloc>::swap(buffer& rhs)
|
||||
{
|
||||
base::swap(rhs);
|
||||
std::swap(ptr_, rhs.ptr_);
|
||||
std::swap(eptr_, rhs.eptr_);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_BUFFERS_HPP_INCLUDED
|
32
boost/iostreams/detail/call_traits.hpp
Normal file
32
boost/iostreams/detail/call_traits.hpp
Normal file
@ -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 <boost/iostreams/traits.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct param_type {
|
||||
typedef typename mpl::if_<is_std_io<T>, T&, const T&>::type type;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct value_type {
|
||||
typedef typename mpl::if_<is_std_io<T>, T&, T>::type type;
|
||||
};
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_VALUE_TYPE_HPP_INCLUDED //-----------//
|
63
boost/iostreams/detail/char_traits.hpp
Normal file
63
boost/iostreams/detail/char_traits.hpp
Normal file
@ -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 <boost/iostreams/char_traits.hpp>, 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 <iosfwd>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifdef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# include <boost/config.hpp> // Make sure size_t is in std.
|
||||
# include <cstddef>
|
||||
# include <cstring>
|
||||
# include <cstdio>
|
||||
#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<char*>(std::memcpy(dest, src, n)); }
|
||||
static char* move(char *dest, const char *src, std::size_t n)
|
||||
{ return static_cast<char*>(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
|
214
boost/iostreams/detail/codecvt_helper.hpp
Normal file
214
boost/iostreams/detail/codecvt_helper.hpp
Normal file
@ -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<typename Intern, typename Extern>
|
||||
// struct mycodecvt : codecvt_helper<Intern, Extern, State> { ... };
|
||||
//
|
||||
// // Or:
|
||||
// struct mycodecvt : codecvt_helper<wchar_t, char, State> { ... };
|
||||
//
|
||||
// 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 <boost/config.hpp> // Put size_t in std, BOOST_MSVC, Dinkum.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <algorithm> // min.
|
||||
#include <cstddef> // size_t.
|
||||
#include <locale> // locale, codecvt_base, codecvt.
|
||||
#include <boost/iostreams/detail/config/codecvt.hpp>
|
||||
|
||||
//------------------Definition of traits--------------------------------------//
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
#if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-----------------------//
|
||||
|
||||
template<typename T>
|
||||
struct codecvt_intern { typedef typename T::intern_type type; };
|
||||
|
||||
template<typename T>
|
||||
struct codecvt_extern { typedef typename T::extern_type type; };
|
||||
|
||||
#else // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //--------------//
|
||||
|
||||
template<typename T>
|
||||
struct codecvt_intern { typedef typename T::from_type type; };
|
||||
|
||||
template<typename T>
|
||||
struct codecvt_extern { typedef typename T::to_type type; };
|
||||
|
||||
#endif // #if !BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) //-------------//
|
||||
|
||||
template<typename T>
|
||||
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<typename Intern, typename Extern, typename State>
|
||||
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<std::size_t>(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<typename Intern, typename Extern> \
|
||||
class codecvt<Intern, Extern, state> \
|
||||
: 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<typename Intern, typename Extern> \
|
||||
std::locale::id codecvt<Intern, Extern, state>::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<typename Intern, typename Extern, typename State>
|
||||
struct codecvt_helper : std::codecvt<Intern, Extern, State> {
|
||||
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<Intern, Extern, State>(refs)
|
||||
#else
|
||||
: std::codecvt<Intern, Extern, State>()
|
||||
#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
|
63
boost/iostreams/detail/codecvt_holder.hpp
Normal file
63
boost/iostreams/detail/codecvt_holder.hpp
Normal file
@ -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 <cwchar> // mbstate_t.
|
||||
#include <locale> // codecvt, locale.
|
||||
#include <boost/config.hpp> // HAS_MACRO_USE_FACET.
|
||||
#include <boost/iostreams/detail/config/codecvt.hpp>
|
||||
|
||||
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<typename Codecvt>
|
||||
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<default_codecvt> {
|
||||
typedef std::codecvt<wchar_t, char, std::mbstate_t> 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
|
49
boost/iostreams/detail/config/auto_link.hpp
Normal file
49
boost/iostreams/detail/config/auto_link.hpp
Normal file
@ -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 <boost/config/auto_link.hpp> 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 <boost/config/auto_link.hpp>
|
||||
#endif // auto-linking disabled
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_AUTO_LINK_HPP_INCLUDED
|
50
boost/iostreams/detail/config/bzip2.hpp
Normal file
50
boost/iostreams/detail/config/bzip2.hpp
Normal file
@ -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 <boost/config/auto_link.hpp> 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/config.hpp> // 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 <boost/config/auto_link.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_BZIP2_HPP_INCLUDED
|
81
boost/iostreams/detail/config/codecvt.hpp
Normal file
81
boost/iostreams/detail/config/codecvt.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#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 <locale>
|
||||
#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
|
30
boost/iostreams/detail/config/disable_warnings.hpp
Normal file
30
boost/iostreams/detail/config/disable_warnings.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp> // 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
|
46
boost/iostreams/detail/config/dyn_link.hpp
Normal file
46
boost/iostreams/detail/config/dyn_link.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
//------------------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
|
18
boost/iostreams/detail/config/enable_warnings.hpp
Normal file
18
boost/iostreams/detail/config/enable_warnings.hpp
Normal file
@ -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
|
45
boost/iostreams/detail/config/fpos.hpp
Normal file
45
boost/iostreams/detail/config/fpos.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
|
||||
# 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 <boost/iostreams/detail/ios.hpp>
|
||||
|
||||
# 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
|
27
boost/iostreams/detail/config/gcc.hpp
Normal file
27
boost/iostreams/detail/config/gcc.hpp
Normal file
@ -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 <boost/config/auto_link.hpp> 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/config.hpp> // 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
|
19
boost/iostreams/detail/config/limits.hpp
Normal file
19
boost/iostreams/detail/config/limits.hpp
Normal file
@ -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
|
30
boost/iostreams/detail/config/overload_resolution.hpp
Normal file
30
boost/iostreams/detail/config/overload_resolution.hpp
Normal file
@ -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 <boost/config/auto_link.hpp> 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/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/config/gcc.hpp>
|
||||
|
||||
#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
|
72
boost/iostreams/detail/config/rtl.hpp
Normal file
72
boost/iostreams/detail/config/rtl.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
|
||||
// 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
|
24
boost/iostreams/detail/config/unreachable_return.hpp
Normal file
24
boost/iostreams/detail/config/unreachable_return.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
|
||||
#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
|
54
boost/iostreams/detail/config/wide_streams.hpp
Normal file
54
boost/iostreams/detail/config/wide_streams.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <cstddef>
|
||||
|
||||
#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
|
25
boost/iostreams/detail/config/windows_posix.hpp
Normal file
25
boost/iostreams/detail/config/windows_posix.hpp
Normal file
@ -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
|
50
boost/iostreams/detail/config/zlib.hpp
Normal file
50
boost/iostreams/detail/config/zlib.hpp
Normal file
@ -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 <boost/config/auto_link.hpp> 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/config.hpp> // 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 <boost/config/auto_link.hpp>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CONFIG_ZLIB_HPP_INCLUDED
|
74
boost/iostreams/detail/counted_array.hpp
Normal file
74
boost/iostreams/detail/counted_array.hpp
Normal file
@ -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 <algorithm> // min.
|
||||
#include <cstddef> // size_t
|
||||
#include <string> // char_traits
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // streamsize.
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Ch>
|
||||
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<char_type>::copy(
|
||||
s,
|
||||
buf_ + ptr_,
|
||||
static_cast<size_t>(result)
|
||||
);
|
||||
ptr_ += result;
|
||||
return result;
|
||||
}
|
||||
std::streamsize count() const { return ptr_; }
|
||||
private:
|
||||
const Ch* buf_;
|
||||
std::streamsize ptr_, end_;
|
||||
};
|
||||
|
||||
template<typename Ch>
|
||||
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<char_type>::copy(
|
||||
buf_ + ptr_,
|
||||
s,
|
||||
static_cast<size_t>(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
|
65
boost/iostreams/detail/current_directory.hpp
Normal file
65
boost/iostreams/detail/current_directory.hpp
Normal file
@ -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 <boost/config.hpp> // make sure size_t is in std.
|
||||
#include <cstddef> // size_t
|
||||
#include <string>
|
||||
#include <boost/iostreams/detail/buffer.hpp>
|
||||
#include <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
#include <boost/iostreams/detail/system_failure.hpp>
|
||||
#ifdef BOOST_IOSTREAMS_WINDOWS
|
||||
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
|
||||
# include <windows.h>
|
||||
#else
|
||||
# include <unistd.h> // sysconf.
|
||||
#endif
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// Returns the current working directory
|
||||
inline std::string current_directory()
|
||||
{
|
||||
#ifdef BOOST_IOSTREAMS_WINDOWS
|
||||
DWORD length;
|
||||
basic_buffer<char> buf(MAX_PATH);
|
||||
while (true) {
|
||||
length = ::GetCurrentDirectoryA(buf.size(), buf.data());
|
||||
if (!length)
|
||||
throw_system_failure("failed determining current directory");
|
||||
if (length < static_cast<DWORD>(buf.size()))
|
||||
break;
|
||||
buf.resize(buf.size() * 2);
|
||||
}
|
||||
return std::string(buf.data(), length);
|
||||
#else // #ifdef BOOST_IOSTREAMS_WINDOWS
|
||||
basic_buffer<char> buf(pathconf(".", _PC_PATH_MAX));
|
||||
if (!getcwd(buf.data(), static_cast<size_t>(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 <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED
|
21
boost/iostreams/detail/default_arg.hpp
Normal file
21
boost/iostreams/detail/default_arg.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
|
||||
// Obsolete. Remove.
|
||||
#define BOOST_IOSTREAMS_DEFAULT_ARG(arg) arg
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DEFAULT_ARG_HPP_INCLUDED
|
41
boost/iostreams/detail/dispatch.hpp
Normal file
41
boost/iostreams/detail/dispatch.hpp
Normal file
@ -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/config.hpp> // BOOST_DEDUCED_TYPENAME.
|
||||
#include <boost/iostreams/detail/select.hpp>
|
||||
#include <boost/iostreams/traits.hpp> // category_of.
|
||||
#include <boost/mpl/void.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
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<T>::type >
|
||||
struct dispatch
|
||||
: iostreams::select< // Disambiguation for Tru64.
|
||||
is_convertible<Category, Tag1>, Tag1,
|
||||
is_convertible<Category, Tag2>, Tag2,
|
||||
is_convertible<Category, Tag3>, Tag3,
|
||||
is_convertible<Category, Tag4>, Tag4,
|
||||
is_convertible<Category, Tag5>, Tag5,
|
||||
is_convertible<Category, Tag6>, Tag6
|
||||
>
|
||||
{ };
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DISPATCH_HPP_INCLUDED
|
114
boost/iostreams/detail/double_object.hpp
Normal file
114
boost/iostreams/detail/double_object.hpp
Normal file
@ -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 <algorithm> // swap.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
|
||||
# include <msl_utility>
|
||||
#else
|
||||
# include <boost/call_traits.hpp>
|
||||
#endif
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
class single_object_holder {
|
||||
public:
|
||||
#if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
|
||||
typedef Metrowerks::call_traits<T> traits_type;
|
||||
#else
|
||||
typedef boost::call_traits<T> 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<typename T>
|
||||
struct double_object_holder {
|
||||
public:
|
||||
#if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
|
||||
typedef Metrowerks::call_traits<T> traits_type;
|
||||
#else
|
||||
typedef boost::call_traits<T> 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<typename T, typename IsDouble>
|
||||
class double_object
|
||||
: public mpl::if_<
|
||||
IsDouble,
|
||||
double_object_holder<T>,
|
||||
single_object_holder<T>
|
||||
>::type
|
||||
{
|
||||
private:
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
IsDouble,
|
||||
double_object_holder<T>,
|
||||
single_object_holder<T>
|
||||
>::type base_type;
|
||||
public:
|
||||
#if BOOST_WORKAROUND(__MWERKS__, > 0x3003)
|
||||
typedef Metrowerks::call_traits<T> traits_type;
|
||||
#else
|
||||
typedef boost::call_traits<T> 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
|
33
boost/iostreams/detail/enable_if_stream.hpp
Normal file
33
boost/iostreams/detail/enable_if_stream.hpp
Normal file
@ -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/config.hpp> // BOOST_NO_SFINAE.
|
||||
#include <boost/config/workaround.hpp>
|
||||
#include <boost/utility/enable_if.hpp>
|
||||
#include <boost/iostreams/traits_fwd.hpp> // 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<T> >::type* = 0 \
|
||||
/**/
|
||||
# define BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) \
|
||||
, typename boost::disable_if< boost::iostreams::is_std_io<T> >::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
|
45
boost/iostreams/detail/error.hpp
Normal file
45
boost/iostreams/detail/error.hpp
Normal file
@ -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 <boost/iostreams/detail/ios.hpp> // 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
|
135
boost/iostreams/detail/execute.hpp
Normal file
135
boost/iostreams/detail/execute.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/config/limits.hpp> // MAX_EXECUTE_ARITY
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/utility/result_of.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// Helper for class template execute_traits.
|
||||
template<typename Result>
|
||||
struct execute_traits_impl {
|
||||
typedef Result result_type;
|
||||
template<typename Op>
|
||||
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<void> {
|
||||
typedef int result_type;
|
||||
template<typename Op>
|
||||
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<Op()>::type
|
||||
#else
|
||||
BOOST_DEDUCED_TYPENAME Op::result_type
|
||||
#endif
|
||||
>
|
||||
struct execute_traits
|
||||
: execute_traits_impl<Result>
|
||||
{ };
|
||||
|
||||
// Implementation with no cleanup operations.
|
||||
template<typename Op>
|
||||
typename execute_traits<Op>::result_type
|
||||
execute_all(Op op)
|
||||
{
|
||||
return execute_traits<Op>::execute(op);
|
||||
}
|
||||
|
||||
// Implementation with one or more cleanup operations
|
||||
#define BOOST_PP_LOCAL_MACRO(n) \
|
||||
template<typename Op, BOOST_PP_ENUM_PARAMS(n, typename C)> \
|
||||
typename execute_traits<Op>::result_type \
|
||||
execute_all(Op op, BOOST_PP_ENUM_BINARY_PARAMS(n, C, c)) \
|
||||
{ \
|
||||
typename execute_traits<Op>::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<class InIt, class Op>
|
||||
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
|
32
boost/iostreams/detail/file_handle.hpp
Normal file
32
boost/iostreams/detail/file_handle.hpp
Normal file
@ -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 <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
|
||||
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
|
113
boost/iostreams/detail/forward.hpp
Normal file
113
boost/iostreams/detail/forward.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC, BOOST_NO_SFINAE
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/config/limits.hpp>
|
||||
#include <boost/iostreams/detail/push_params.hpp>
|
||||
#include <boost/preprocessor/arithmetic/dec.hpp>
|
||||
#include <boost/preprocessor/arithmetic/inc.hpp>
|
||||
#include <boost/preprocessor/punctuation/comma_if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_binary_params.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
#include <boost/preprocessor/repetition/repeat_from_to.hpp>
|
||||
#include <boost/preprocessor/tuple/elem.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
//------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<device>& 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<device>& 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_ENUM_PARAMS_Z(z, n, typename U)> \
|
||||
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<BOOST_PP_ENUM_PARAMS_Z(z, n, typename U)> \
|
||||
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<device, param> >::type* = 0 \
|
||||
/**/
|
||||
#else
|
||||
# define BOOST_IOSTREAMS_DISABLE_IF_SAME(device, param)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FORWARD_HPP_INCLUDED
|
33
boost/iostreams/detail/fstream.hpp
Normal file
33
boost/iostreams/detail/fstream.hpp
Normal file
@ -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 <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# include <fstream>
|
||||
#else
|
||||
# include <fstream.h>
|
||||
#endif
|
||||
|
||||
#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# define BOOST_IOSTREAMS_BASIC_IFSTREAM(Ch, Tr) std::basic_ifstream<Ch, Tr>
|
||||
# define BOOST_IOSTREAMS_BASIC_OFSTREAM(Ch, Tr) std::basic_ofstream<Ch, Tr>
|
||||
# define BOOST_IOSTREAMS_BASIC_FSTREAM(Ch, Tr) std::basic_fstream<Ch, Tr>
|
||||
# define BOOST_IOSTREAMS_BASIC_FILEBUF(Ch) std::basic_filebuf<Ch>
|
||||
#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
|
189
boost/iostreams/detail/functional.hpp
Normal file
189
boost/iostreams/detail/functional.hpp
Normal file
@ -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 <boost/iostreams/close.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // BOOST_IOS
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// Function objects and object generators for invoking
|
||||
// boost::iostreams::close
|
||||
|
||||
template<typename T>
|
||||
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<typename T, typename Sink>
|
||||
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<typename T>
|
||||
device_close_operation<T>
|
||||
call_close(T& t, BOOST_IOS::openmode which)
|
||||
{ return device_close_operation<T>(t, which); }
|
||||
|
||||
template<typename T, typename Sink>
|
||||
filter_close_operation<T, Sink>
|
||||
call_close(T& t, Sink& snk, BOOST_IOS::openmode which)
|
||||
{ return filter_close_operation<T, Sink>(t, snk, which); }
|
||||
|
||||
// Function objects and object generators for invoking
|
||||
// boost::iostreams::detail::close_all
|
||||
|
||||
template<typename T>
|
||||
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<typename T, typename Sink>
|
||||
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<typename T>
|
||||
device_close_all_operation<T> call_close_all(T& t)
|
||||
{ return device_close_all_operation<T>(t); }
|
||||
|
||||
template<typename T, typename Sink>
|
||||
filter_close_all_operation<T, Sink>
|
||||
call_close_all(T& t, Sink& snk)
|
||||
{ return filter_close_all_operation<T, Sink>(t, snk); }
|
||||
|
||||
// Function object and object generator for invoking a
|
||||
// member function void close(std::ios_base::openmode)
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
member_close_operation<T> call_member_close(T& t, BOOST_IOS::openmode which)
|
||||
{ return member_close_operation<T>(t, which); }
|
||||
|
||||
// Function object and object generator for invoking a
|
||||
// member function void reset()
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
reset_operation<T> call_reset(T& t) { return reset_operation<T>(t); }
|
||||
|
||||
// Function object and object generator for clearing a flag
|
||||
|
||||
template<typename T>
|
||||
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<typename T>
|
||||
clear_flags_operation<T> clear_flags(T& t)
|
||||
{ return clear_flags_operation<T>(t); }
|
||||
|
||||
// Function object and generator for flushing a buffer
|
||||
|
||||
// Function object for use with execute_all()
|
||||
template<typename Buffer, typename Device>
|
||||
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<typename Buffer, typename Device>
|
||||
flush_buffer_operation<Buffer, Device>
|
||||
flush_buffer(Buffer& buf, Device& dev, bool flush)
|
||||
{ return flush_buffer_operation<Buffer, Device>(buf, dev, flush); }
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_FUNCTIONAL_HPP_INCLUDED
|
65
boost/iostreams/detail/ios.hpp
Normal file
65
boost/iostreams/detail/ios.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# if !BOOST_WORKAROUND(__MWERKS__, <= 0x3003)
|
||||
# include <ios>
|
||||
# else
|
||||
# include <istream>
|
||||
# include <ostream>
|
||||
# endif
|
||||
#else
|
||||
# include <exception>
|
||||
# include <iosfwd>
|
||||
#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
|
34
boost/iostreams/detail/iostream.hpp
Normal file
34
boost/iostreams/detail/iostream.hpp
Normal file
@ -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 <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# include <istream>
|
||||
# include <ostream>
|
||||
#else
|
||||
# include <iostream.h>
|
||||
#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
|
80
boost/iostreams/detail/is_dereferenceable.hpp
Normal file
80
boost/iostreams/detail/is_dereferenceable.hpp
Normal file
@ -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 <boost/type_traits/remove_cv.hpp>
|
||||
# include <boost/mpl/aux_/lambda_support.hpp>
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/detail/workaround.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// is_dereferenceable<T> 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 <class T> 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 <class T>
|
||||
char check_increment(T const&);
|
||||
|
||||
template <class T>
|
||||
struct impl
|
||||
{
|
||||
static typename boost::remove_cv<T>::type& x;
|
||||
|
||||
BOOST_STATIC_CONSTANT(
|
||||
bool
|
||||
, value = sizeof(is_dereferenceable_::check_increment(BOOST_comma(*x,0))) == 1
|
||||
);
|
||||
};
|
||||
}
|
||||
|
||||
# undef BOOST_comma
|
||||
|
||||
template<typename T>
|
||||
struct is_dereferenceable
|
||||
: public ::boost::integral_constant<bool, is_dereferenceable_::impl<T>::value >
|
||||
{
|
||||
BOOST_MPL_AUX_LAMBDA_SUPPORT(1,is_dereferenceable,(T))
|
||||
};
|
||||
|
||||
} }
|
||||
|
||||
|
||||
} // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // BOOST_IOSTREAMS_DETAIL_IS_DEREFERENCEABLE_HPP_INCLUDED
|
34
boost/iostreams/detail/is_iterator_range.hpp
Normal file
34
boost/iostreams/detail/is_iterator_range.hpp
Normal file
@ -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 <boost/config.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/bool_trait_def.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
namespace boost {
|
||||
|
||||
// We avoid dependence on Boost.Range by using a forward declaration.
|
||||
template<typename Iterator>
|
||||
class iterator_range;
|
||||
|
||||
namespace iostreams {
|
||||
|
||||
BOOST_IOSTREAMS_BOOL_TRAIT_DEF(is_iterator_range, boost::iterator_range, 1)
|
||||
|
||||
} // End namespace iostreams.
|
||||
|
||||
} // End namespace boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED
|
32
boost/iostreams/detail/newline.hpp
Normal file
32
boost/iostreams/detail/newline.hpp
Normal file
@ -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<typename Ch>
|
||||
struct newline;
|
||||
|
||||
template<>
|
||||
struct newline<char> {
|
||||
BOOST_STATIC_CONSTANT(char, value = '\n');
|
||||
};
|
||||
|
||||
template<>
|
||||
struct newline<wchar_t> {
|
||||
BOOST_STATIC_CONSTANT(wchar_t, value = L'\n');
|
||||
};
|
||||
|
||||
} } } // End namespaces detaill, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_NEWLINE_HPP_INCLUDED
|
114
boost/iostreams/detail/optional.hpp
Normal file
114
boost/iostreams/detail/optional.hpp
Normal file
@ -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 <boost/assert.hpp>
|
||||
#include <boost/mpl/int.hpp>
|
||||
#include <boost/type_traits/aligned_storage.hpp>
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
// Taken from <boost/optional.hpp>.
|
||||
template<class T>
|
||||
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<T>::value >::type aligner_;
|
||||
} dummy_ ;
|
||||
|
||||
public:
|
||||
|
||||
void const* address() const { return &dummy_.data[0]; }
|
||||
void * address() { return &dummy_.data[0]; }
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
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<T*>(address());
|
||||
}
|
||||
const T& operator*() const
|
||||
{
|
||||
BOOST_ASSERT(initialized_);
|
||||
return *static_cast<const T*>(address());
|
||||
}
|
||||
T* operator->()
|
||||
{
|
||||
BOOST_ASSERT(initialized_);
|
||||
return static_cast<T*>(address());
|
||||
}
|
||||
const T* operator->() const
|
||||
{
|
||||
BOOST_ASSERT(initialized_);
|
||||
return static_cast<const T*>(address());
|
||||
}
|
||||
T* get()
|
||||
{
|
||||
BOOST_ASSERT(initialized_);
|
||||
return static_cast<T*>(address());
|
||||
}
|
||||
const T* get() const
|
||||
{
|
||||
BOOST_ASSERT(initialized_);
|
||||
return static_cast<const T*>(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<T*>(address());
|
||||
t->~T();
|
||||
#else
|
||||
static_cast<T*>(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<T> storage_;
|
||||
bool initialized_;
|
||||
};
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_OPTIONAL_HPP_INCLUDED
|
27
boost/iostreams/detail/param_type.hpp
Normal file
27
boost/iostreams/detail/param_type.hpp
Normal file
@ -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 <boost/iostreams/traits.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename T>
|
||||
struct param_type {
|
||||
typedef typename mpl::if_<is_std_io<T>, T&, const T&>::type type;
|
||||
};
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PARAM_TYPE_HPP_INCLUDED //-----------//
|
214
boost/iostreams/detail/path.hpp
Normal file
214
boost/iostreams/detail/path.hpp
Normal file
@ -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 <cstring>
|
||||
#include <string>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
|
||||
# include <cwchar>
|
||||
#endif
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
#ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS //------------------------------------//
|
||||
|
||||
class path {
|
||||
template<typename T, typename V>
|
||||
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<typename Path>
|
||||
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<typename Path>
|
||||
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 Path>
|
||||
typename sfinae<typename Path::external_string_type, path&>::type
|
||||
operator=(const Path& p)
|
||||
{
|
||||
init(p.external_file_string());
|
||||
return *this;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Assignment operator taking a boost::filesystem3::path
|
||||
template<typename Path>
|
||||
typename sfinae<typename Path::codecvt_type, path&>::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<typename Path>
|
||||
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<typename Path>
|
||||
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
|
153
boost/iostreams/detail/push.hpp
Normal file
153
boost/iostreams/detail/push.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/adapter/range_adapter.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/detail/push_params.hpp>
|
||||
#include <boost/iostreams/detail/resolve.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/control/iif.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
//
|
||||
// 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<mode, ch>(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<typename CharType, typename TraitsType> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(::std::basic_streambuf<CharType, TraitsType>& sb BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, sb, helper, has_return); } \
|
||||
template<typename CharType, typename TraitsType> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(::std::basic_istream<CharType, TraitsType>& is BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_STATIC_ASSERT((!is_convertible<mode, output>::value)); \
|
||||
BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, is, helper, has_return); } \
|
||||
template<typename CharType, typename TraitsType> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(::std::basic_ostream<CharType, TraitsType>& os BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_STATIC_ASSERT((!is_convertible<mode, input>::value)); \
|
||||
BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, os, helper, has_return); } \
|
||||
template<typename CharType, typename TraitsType> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(::std::basic_iostream<CharType, TraitsType>& io BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_IOSTREAMS_ADAPT_STREAM(mode, ch, io, helper, has_return); } \
|
||||
template<typename Iter> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(const iterator_range<Iter>& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_PP_EXPR_IF(has_return, return) \
|
||||
this->helper( ::boost::iostreams::detail::range_adapter< \
|
||||
mode, iterator_range<Iter> \
|
||||
>(rng) \
|
||||
BOOST_IOSTREAMS_PUSH_ARGS() ); } \
|
||||
template<typename Pipeline, typename Concept> \
|
||||
BOOST_PP_IIF(has_return, result, explicit) \
|
||||
name(const ::boost::iostreams::pipeline<Pipeline, Concept>& p) \
|
||||
{ p.push(*this); } \
|
||||
template<typename T> \
|
||||
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<mode, ch>(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<mode, output>::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<mode, input>::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<typename Iter> \
|
||||
BOOST_PP_IF(has_return, result, explicit) \
|
||||
name(const iterator_range<Iter>& rng BOOST_IOSTREAMS_PUSH_PARAMS()) \
|
||||
{ BOOST_PP_EXPR_IF(has_return, return) \
|
||||
this->helper( ::boost::iostreams::detail::range_adapter< \
|
||||
mode, iterator_range<Iter> \
|
||||
>(rng) \
|
||||
BOOST_IOSTREAMS_PUSH_ARGS() ); } \
|
||||
template<typename Pipeline, typename Concept> \
|
||||
BOOST_PP_IF(has_return, result, explicit) \
|
||||
name(const ::boost::iostreams::pipeline<Pipeline, Concept>& p) \
|
||||
{ p.push(*this); } \
|
||||
template<typename T> \
|
||||
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<mode, ch>(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<typename T> \
|
||||
void BOOST_PP_CAT(name, _msvc_impl) \
|
||||
( ::boost::mpl::true_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \
|
||||
{ t.push(*this); } \
|
||||
template<typename T> \
|
||||
void BOOST_PP_CAT(name, _msvc_impl) \
|
||||
( ::boost::mpl::false_, const T& t BOOST_IOSTREAMS_PUSH_PARAMS() ) \
|
||||
{ this->helper( ::boost::iostreams::detail::resolve<mode, ch>(t) \
|
||||
BOOST_IOSTREAMS_PUSH_ARGS() ); } \
|
||||
template<typename T> \
|
||||
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>(), \
|
||||
t BOOST_IOSTREAMS_PUSH_ARGS() ); \
|
||||
} \
|
||||
/**/
|
||||
#endif // #if VC6, VC7.0, Borland 5.x
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_PUSH_HPP_INCLUDED
|
21
boost/iostreams/detail/push_params.hpp
Normal file
21
boost/iostreams/detail/push_params.hpp
Normal file
@ -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
|
230
boost/iostreams/detail/resolve.hpp
Normal file
230
boost/iostreams/detail/resolve.hpp
Normal file
@ -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 <boost/config.hpp> // partial spec, put size_t in std.
|
||||
#include <cstddef> // std::size_t.
|
||||
#include <boost/detail/is_incrementable.hpp>
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/adapter/mode_adapter.hpp>
|
||||
#include <boost/iostreams/detail/adapter/output_iterator_adapter.hpp>
|
||||
#include <boost/iostreams/detail/adapter/range_adapter.hpp>
|
||||
#include <boost/iostreams/detail/config/gcc.hpp>
|
||||
#include <boost/iostreams/detail/config/overload_resolution.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
#include <boost/iostreams/detail/is_dereferenceable.hpp>
|
||||
#include <boost/iostreams/detail/is_iterator_range.hpp>
|
||||
#include <boost/iostreams/detail/select.hpp>
|
||||
#include <boost/iostreams/detail/wrap_unwrap.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/mpl/and.hpp>
|
||||
#include <boost/mpl/bool.hpp> // true_.
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/range/iterator_range.hpp>
|
||||
#include <boost/type_traits/is_array.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // VC7.1 C4224.
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
//------------------Definition of resolve-------------------------------------//
|
||||
|
||||
#ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //-------------------------//
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
struct resolve_traits {
|
||||
typedef typename
|
||||
mpl::if_<
|
||||
boost::detail::is_incrementable<T>,
|
||||
output_iterator_adapter<Mode, Ch, T>,
|
||||
const T&
|
||||
>::type type;
|
||||
};
|
||||
|
||||
# ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------------------//
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::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<T> >::type* = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(t);
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch, typename Tr>
|
||||
mode_adapter< Mode, std::basic_streambuf<Ch, Tr> >
|
||||
resolve(std::basic_streambuf<Ch, Tr>& sb)
|
||||
{ return mode_adapter< Mode, std::basic_streambuf<Ch, Tr> >(wrap(sb)); }
|
||||
|
||||
template<typename Mode, typename Ch, typename Tr>
|
||||
mode_adapter< Mode, std::basic_istream<Ch, Tr> >
|
||||
resolve(std::basic_istream<Ch, Tr>& is)
|
||||
{ return mode_adapter< Mode, std::basic_istream<Ch, Tr> >(wrap(is)); }
|
||||
|
||||
template<typename Mode, typename Ch, typename Tr>
|
||||
mode_adapter< Mode, std::basic_ostream<Ch, Tr> >
|
||||
resolve(std::basic_ostream<Ch, Tr>& os)
|
||||
{ return mode_adapter< Mode, std::basic_ostream<Ch, Tr> >(wrap(os)); }
|
||||
|
||||
template<typename Mode, typename Ch, typename Tr>
|
||||
mode_adapter< Mode, std::basic_iostream<Ch, Tr> >
|
||||
resolve(std::basic_iostream<Ch, Tr>& io)
|
||||
{ return mode_adapter< Mode, std::basic_iostream<Ch, Tr> >(wrap(io)); }
|
||||
|
||||
template<typename Mode, typename Ch, std::size_t N>
|
||||
array_adapter<Mode, Ch> resolve(Ch (&array)[N])
|
||||
{ return array_adapter<Mode, Ch>(array); }
|
||||
|
||||
template<typename Mode, typename Ch, typename Iter>
|
||||
range_adapter< Mode, boost::iterator_range<Iter> >
|
||||
resolve(const boost::iterator_range<Iter>& rng)
|
||||
{ return range_adapter< Mode, boost::iterator_range<Iter> >(rng); }
|
||||
|
||||
# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //---------------------//
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve( const T& t
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(T)
|
||||
#if defined(__GNUC__)
|
||||
, typename disable_if< is_iterator_range<T> >::type* = 0
|
||||
#endif
|
||||
)
|
||||
{
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(t);
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
mode_adapter<Mode, std::streambuf>
|
||||
resolve(std::streambuf& sb)
|
||||
{ return mode_adapter<Mode, std::streambuf>(wrap(sb)); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
mode_adapter<Mode, std::istream>
|
||||
resolve(std::istream& is)
|
||||
{ return mode_adapter<Mode, std::istream>(wrap(is)); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
mode_adapter<Mode, std::ostream>
|
||||
resolve(std::ostream& os)
|
||||
{ return mode_adapter<Mode, std::ostream>(wrap(os)); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
mode_adapter<Mode, std::iostream>
|
||||
resolve(std::iostream& io)
|
||||
{ return mode_adapter<Mode, std::iostream>(wrap(io)); }
|
||||
|
||||
template<typename Mode, typename Ch, std::size_t N>
|
||||
array_adapter<Mode, Ch> resolve(Ch (&array)[N])
|
||||
{ return array_adapter<Mode, Ch>(array); }
|
||||
|
||||
template<typename Mode, typename Ch, typename Iter>
|
||||
range_adapter< Mode, boost::iterator_range<Iter> >
|
||||
resolve(const boost::iterator_range<Iter>& rng)
|
||||
{ return range_adapter< Mode, boost::iterator_range<Iter> >(rng); }
|
||||
|
||||
# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
|
||||
#else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //----------------//
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
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<T>,
|
||||
mode_adapter<Mode, T>,
|
||||
is_iterator_range<T>,
|
||||
range_adapter<Mode, T>,
|
||||
is_dereferenceable<T>,
|
||||
output_iterator_adapter<Mode, Ch, T>,
|
||||
is_array<T>,
|
||||
array_adapter<Mode, T>,
|
||||
else_,
|
||||
#if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
const T&
|
||||
#else
|
||||
T
|
||||
#endif
|
||||
>::type type;
|
||||
};
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(const T& t, mpl::true_)
|
||||
{ // Bad overload resolution.
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(wrap(const_cast<T&>(t)));
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(const T& t, mpl::false_)
|
||||
{
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(t);
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T))
|
||||
{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \
|
||||
!defined(__GNUC__) // ---------------------------------------------------//
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(T& t, mpl::true_)
|
||||
{
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(wrap(t));
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(T& t, mpl::false_)
|
||||
{
|
||||
typedef typename resolve_traits<Mode, Ch, T>::type return_type;
|
||||
return return_type(t);
|
||||
}
|
||||
|
||||
template<typename Mode, typename Ch, typename T>
|
||||
typename resolve_traits<Mode, Ch, T>::type
|
||||
resolve(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T))
|
||||
{ return resolve<Mode, Ch>(t, is_std_io<T>()); }
|
||||
|
||||
# endif // Borland 5.x or GCC //--------------------------------//
|
||||
#endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp> // VC7.1 4224.
|
||||
|
||||
#endif // BOOST_IOSTREAMS_DETAIL_RESOLVE_HPP_INCLUDED
|
483
boost/iostreams/detail/restrict_impl.hpp
Normal file
483
boost/iostreams/detail/restrict_impl.hpp
Normal file
@ -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 <boost/iostreams/restrict.hpp> and
|
||||
* <boost/iostreams/slice.hpp> 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 <algorithm> // min.
|
||||
# include <utility> // pair.
|
||||
# include <boost/cstdint.hpp> // intmax_t.
|
||||
# include <boost/config.hpp> // DEDUCED_TYPENAME.
|
||||
# include <boost/iostreams/categories.hpp>
|
||||
# include <boost/iostreams/char_traits.hpp>
|
||||
# include <boost/iostreams/detail/adapter/device_adapter.hpp>
|
||||
# include <boost/iostreams/detail/adapter/filter_adapter.hpp>
|
||||
# include <boost/iostreams/detail/call_traits.hpp>
|
||||
# include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
# include <boost/iostreams/detail/error.hpp>
|
||||
# include <boost/iostreams/detail/ios.hpp> // failure.
|
||||
# include <boost/iostreams/detail/select.hpp>
|
||||
# include <boost/iostreams/operations.hpp>
|
||||
# include <boost/iostreams/skip.hpp>
|
||||
# include <boost/iostreams/traits.hpp> // mode_of, is_direct.
|
||||
# include <boost/mpl/bool.hpp>
|
||||
# include <boost/static_assert.hpp>
|
||||
# include <boost/throw_exception.hpp>
|
||||
# include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
# include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
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<typename Device>
|
||||
class restricted_indirect_device : public device_adapter<Device> {
|
||||
private:
|
||||
typedef typename detail::param_type<Device>::type param_type;
|
||||
public:
|
||||
typedef typename char_type_of<Device>::type char_type;
|
||||
typedef typename mode_of<Device>::type mode;
|
||||
BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::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<typename Device>
|
||||
class restricted_direct_device : public device_adapter<Device> {
|
||||
public:
|
||||
typedef typename char_type_of<Device>::type char_type;
|
||||
typedef std::pair<char_type*, char_type*> pair_type;
|
||||
typedef typename mode_of<Device>::type mode;
|
||||
BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::value));
|
||||
struct category
|
||||
: mode_of<Device>::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<typename Filter>
|
||||
class restricted_filter : public filter_adapter<Filter> {
|
||||
public:
|
||||
typedef typename char_type_of<Filter>::type char_type;
|
||||
typedef typename mode_of<Filter>::type mode;
|
||||
BOOST_STATIC_ASSERT(!(is_convertible<mode, detail::two_sequence>::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<typename Source>
|
||||
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<std::streamsize>(end_ - pos_)) :
|
||||
n;
|
||||
std::streamsize result =
|
||||
iostreams::read(this->component(), src, s, amt);
|
||||
if (result != -1)
|
||||
pos_ += result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
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<typename Device>
|
||||
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<typename Device>
|
||||
void close(Device& dev)
|
||||
{
|
||||
open_ = false;
|
||||
detail::close_all(this->component(), dev);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
void close(Device& dev, BOOST_IOS::openmode which)
|
||||
{
|
||||
open_ = false;
|
||||
iostreams::close(this->component(), dev, which);
|
||||
}
|
||||
private:
|
||||
template<typename Device>
|
||||
void open(Device& dev, BOOST_IOS::openmode which)
|
||||
{
|
||||
typedef typename is_convertible<mode, dual_use>::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<typename T>
|
||||
struct restriction_traits
|
||||
: iostreams::select< // Disambiguation for Tru64.
|
||||
is_filter<T>, restricted_filter<T>,
|
||||
is_direct<T>, restricted_direct_device<T>,
|
||||
else_, restricted_indirect_device<T>
|
||||
>
|
||||
{ };
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename T>
|
||||
struct restriction : public detail::restriction_traits<T>::type {
|
||||
typedef typename detail::param_type<T>::type param_type;
|
||||
typedef typename detail::restriction_traits<T>::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<typename Device>
|
||||
restricted_indirect_device<Device>::restricted_indirect_device
|
||||
(param_type dev, stream_offset off, stream_offset len)
|
||||
: device_adapter<Device>(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<typename Device>
|
||||
inline std::streamsize restricted_indirect_device<Device>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{
|
||||
using namespace std;
|
||||
std::streamsize amt =
|
||||
end_ != -1 ?
|
||||
(std::min) (n, static_cast<std::streamsize>(end_ - pos_)) :
|
||||
n;
|
||||
std::streamsize result = iostreams::read(this->component(), s, amt);
|
||||
if (result != -1)
|
||||
pos_ += result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
inline std::streamsize restricted_indirect_device<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<typename Device>
|
||||
std::streampos restricted_indirect_device<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<typename Device>
|
||||
restricted_direct_device<Device>::restricted_direct_device
|
||||
(const Device& dev, stream_offset off, stream_offset len)
|
||||
: device_adapter<Device>(dev), beg_(0), end_(0)
|
||||
{
|
||||
std::pair<char_type*, char_type*> seq =
|
||||
sequence(is_convertible<category, input>());
|
||||
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 Device>
|
||||
typename restricted_direct_device<Device>::pair_type
|
||||
restricted_direct_device<Device>::input_sequence()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_convertible<category, input>::value));
|
||||
return std::make_pair(beg_, end_);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
typename restricted_direct_device<Device>::pair_type
|
||||
restricted_direct_device<Device>::output_sequence()
|
||||
{
|
||||
BOOST_STATIC_ASSERT((is_convertible<category, output>::value));
|
||||
return std::make_pair(beg_, end_);
|
||||
}
|
||||
|
||||
template<typename Device>
|
||||
typename restricted_direct_device<Device>::pair_type
|
||||
restricted_direct_device<Device>::sequence(mpl::true_)
|
||||
{ return iostreams::input_sequence(this->component()); }
|
||||
|
||||
template<typename Device>
|
||||
typename restricted_direct_device<Device>::pair_type
|
||||
restricted_direct_device<Device>::sequence(mpl::false_)
|
||||
{ return iostreams::output_sequence(this->component()); }
|
||||
|
||||
//--------------Implementation of restricted_filter---------------------------//
|
||||
|
||||
template<typename Filter>
|
||||
restricted_filter<Filter>::restricted_filter
|
||||
(const Filter& flt, stream_offset off, stream_offset len)
|
||||
: filter_adapter<Filter>(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<typename T>
|
||||
restriction<T>
|
||||
BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
|
||||
{ return restriction<T>(t, off, len); }
|
||||
|
||||
template<typename Ch, typename Tr>
|
||||
restriction< std::basic_streambuf<Ch, Tr> >
|
||||
BOOST_IOSTREAMS_RESTRICT( std::basic_streambuf<Ch, Tr>& sb, stream_offset off,
|
||||
stream_offset len = -1 )
|
||||
{ return restriction< std::basic_streambuf<Ch, Tr> >(sb, off, len); }
|
||||
|
||||
template<typename Ch, typename Tr>
|
||||
restriction< std::basic_istream<Ch, Tr> >
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::basic_istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction< std::basic_istream<Ch, Tr> >(is, off, len); }
|
||||
|
||||
template<typename Ch, typename Tr>
|
||||
restriction< std::basic_ostream<Ch, Tr> >
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::basic_ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction< std::basic_ostream<Ch, Tr> >(os, off, len); }
|
||||
|
||||
template<typename Ch, typename Tr>
|
||||
restriction< std::basic_iostream<Ch, Tr> >
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::basic_iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction< std::basic_iostream<Ch, Tr> >(io, off, len); }
|
||||
|
||||
# else // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //--------------------//
|
||||
|
||||
template<typename T>
|
||||
restriction<T>
|
||||
BOOST_IOSTREAMS_RESTRICT( const T& t, stream_offset off, stream_offset len = -1
|
||||
BOOST_IOSTREAMS_DISABLE_IF_STREAM(T) )
|
||||
{ return restriction<T>(t, off, len); }
|
||||
|
||||
restriction<std::streambuf>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::streambuf& sb, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction<std::streambuf>(sb, off, len); }
|
||||
|
||||
restriction<std::istream>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::istream<Ch, Tr>& is, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction<std::istream>(is, off, len); }
|
||||
|
||||
restriction<std::ostream>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::ostream<Ch, Tr>& os, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction<std::ostream>(os, off, len); }
|
||||
|
||||
restriction<std::iostream>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(std::iostream<Ch, Tr>& io, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction<std::iostream>(io, off, len); }
|
||||
|
||||
# endif // # ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES //-------------------//
|
||||
# else // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //---------------//
|
||||
|
||||
template<typename T>
|
||||
restriction<T>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(const T& t, stream_offset off, stream_offset len, mpl::true_)
|
||||
{ // Bad overload resolution.
|
||||
return restriction<T>(const_cast<T&>(t, off, len));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
restriction<T>
|
||||
BOOST_IOSTREAMS_RESTRICT
|
||||
(const T& t, stream_offset off, stream_offset len, mpl::false_)
|
||||
{ return restriction<T>(t, off, len); }
|
||||
|
||||
template<typename T>
|
||||
restriction<T>
|
||||
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<T>()); }
|
||||
|
||||
# if !BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600) && \
|
||||
!defined(__GNUC__) // ---------------------------------------------------//
|
||||
|
||||
template<typename T>
|
||||
restriction<T>
|
||||
BOOST_IOSTREAMS_RESTRICT(T& t, stream_offset off, stream_offset len = -1)
|
||||
{ return restriction<T>(t, off, len); }
|
||||
|
||||
# endif // Borland 5.x or GCC //-------------------------------//
|
||||
# endif // #ifndef BOOST_IOSTREAMS_BROKEN_OVERLOAD_RESOLUTION //--------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
# include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #if !defined(BOOST_IOSTREAMS_RESTRICT_IMPL_HPP_INCLUDED) ...
|
86
boost/iostreams/detail/select.hpp
Normal file
86
boost/iostreams/detail/select.hpp
Normal file
@ -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 <boost/type_traits/is_base_and_derived.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/mpl/void.hpp>
|
||||
|
||||
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<Type1>, mpl::eval_if<
|
||||
Case2, mpl::identity<Type2>, mpl::eval_if<
|
||||
Case3, mpl::identity<Type3>, mpl::eval_if<
|
||||
Case4, mpl::identity<Type4>, mpl::eval_if<
|
||||
Case5, mpl::identity<Type5>, mpl::eval_if<
|
||||
Case6, mpl::identity<Type6>, mpl::eval_if<
|
||||
Case7, mpl::identity<Type7>, mpl::eval_if<
|
||||
Case8, mpl::identity<Type8>, mpl::eval_if<
|
||||
Case9, mpl::identity<Type9>, mpl::eval_if<
|
||||
Case10, mpl::identity<Type10>, mpl::eval_if<
|
||||
Case11, mpl::identity<Type11>, mpl::if_<
|
||||
Case12, Type12, mpl::void_ > > > > > > > > > > >
|
||||
>::type type;
|
||||
};
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_SELECT_HPP_INCLUDED
|
161
boost/iostreams/detail/select_by_size.hpp
Normal file
161
boost/iostreams/detail/select_by_size.hpp
Normal file
@ -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_<N>
|
||||
// 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 <boost/utility/select_by_size.hpp>
|
||||
//
|
||||
// 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_<N> 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_<N>) > has not been
|
||||
// specialized.
|
||||
#define SELECT_BY_SIZE_MAX_SPECIALIZED 20
|
||||
|
||||
#include <boost/config.hpp> // BOOST_STATIC_CONSTANT.
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/preprocessor/iteration/local.hpp>
|
||||
|
||||
/* Alternative implementation using max_align.
|
||||
|
||||
#include <boost/type_traits/alignment_of.hpp>
|
||||
#include <boost/type_traits/type_with_alignment.hpp>
|
||||
|
||||
namespace boost { namespace utility {
|
||||
|
||||
template<int N>
|
||||
struct case_ { char c[(N + 1) * alignment_of<detail::max_align>::value]; };
|
||||
|
||||
template<unsigned Size>
|
||||
struct select_by_size {
|
||||
BOOST_STATIC_CONSTANT(int, value =
|
||||
(Size / alignment_of<detail::max_align>::value - 1));
|
||||
};
|
||||
|
||||
} } // End namespaces utility, boost.
|
||||
|
||||
*/ // End alternate implementation.
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
//--------------Definition of case_-------------------------------------------//
|
||||
|
||||
template<int N> struct case_ { char c1; case_<N - 1> c2; };
|
||||
template<> struct case_<-1> { char c; };
|
||||
typedef case_<true> yes_type;
|
||||
typedef case_<false> no_type;
|
||||
|
||||
//--------------Declaration of select_by_size---------------------------------//
|
||||
|
||||
template<unsigned Size> struct select_by_size;
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
//--------------Definition of SELECT_BY_SIZE_SPEC-----------------------------//
|
||||
|
||||
// Sepecializes select_by_size for sizeof(case<n-1>). 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_<n - 1>); \
|
||||
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
|
34
boost/iostreams/detail/streambuf.hpp
Normal file
34
boost/iostreams/detail/streambuf.hpp
Normal file
@ -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 <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_STREAM_TEMPLATES
|
||||
# include <streambuf>
|
||||
#else
|
||||
# include <streambuf.h>
|
||||
#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
|
113
boost/iostreams/detail/streambuf/chainbuf.hpp
Normal file
113
boost/iostreams/detail/streambuf/chainbuf.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC, template friends.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/chain.hpp>
|
||||
#include <boost/iostreams/detail/access_control.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/streambuf.hpp>
|
||||
#include <boost/iostreams/detail/streambuf/linked_streambuf.hpp>
|
||||
#include <boost/iostreams/detail/translate_int_type.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/noncopyable.hpp>
|
||||
|
||||
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<typename Chain, typename Mode, typename Access>
|
||||
class chainbuf
|
||||
: public BOOST_IOSTREAMS_BASIC_STREAMBUF(
|
||||
typename Chain::char_type,
|
||||
typename Chain::traits_type
|
||||
),
|
||||
public access_control<typename Chain::client_type, Access>,
|
||||
private noncopyable
|
||||
{
|
||||
private:
|
||||
typedef access_control<chain_client<Chain>, Access> client_type;
|
||||
public:
|
||||
typedef typename Chain::char_type char_type;
|
||||
BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(typename Chain::traits_type)
|
||||
protected:
|
||||
typedef linked_streambuf<char_type, traits_type> 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<std_traits, chain_traits>(c); }
|
||||
|
||||
delegate_type& delegate()
|
||||
{ return static_cast<delegate_type&>(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<Chain, Mode, Access>* buf) : buf_(buf)
|
||||
{ buf_->set_pointers(); }
|
||||
~sentry() { buf_->get_pointers(); }
|
||||
chainbuf<Chain, Mode, Access>* buf_;
|
||||
};
|
||||
friend struct sentry;
|
||||
Chain chain_;
|
||||
};
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CHAINBUF_HPP_INCLUDED
|
311
boost/iostreams/detail/streambuf/direct_streambuf.hpp
Normal file
311
boost/iostreams/detail/streambuf/direct_streambuf.hpp
Normal file
@ -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 <boost/assert.hpp>
|
||||
#include <cstddef>
|
||||
#include <utility> // pair.
|
||||
#include <boost/config.hpp> // BOOST_DEDUCED_TYPENAME,
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp> // member template friends.
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
#include <boost/iostreams/detail/functional.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/detail/optional.hpp>
|
||||
#include <boost/iostreams/detail/streambuf.hpp>
|
||||
#include <boost/iostreams/detail/streambuf/linked_streambuf.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template< typename T,
|
||||
typename Tr =
|
||||
BOOST_IOSTREAMS_CHAR_TRAITS(
|
||||
BOOST_DEDUCED_TYPENAME char_type_of<T>::type
|
||||
) >
|
||||
class direct_streambuf
|
||||
: public linked_streambuf<BOOST_DEDUCED_TYPENAME char_type_of<T>::type, Tr>
|
||||
{
|
||||
public:
|
||||
typedef typename char_type_of<T>::type char_type;
|
||||
BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
|
||||
private:
|
||||
typedef linked_streambuf<char_type, traits_type> base_type;
|
||||
typedef typename category_of<T>::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<T> storage_;
|
||||
char_type *ibeg_, *iend_, *obeg_, *oend_;
|
||||
bool auto_close_;
|
||||
};
|
||||
|
||||
//------------------Implementation of direct_streambuf------------------------//
|
||||
|
||||
template<typename T, typename Tr>
|
||||
direct_streambuf<T, Tr>::direct_streambuf()
|
||||
: ibeg_(0), iend_(0), obeg_(0), oend_(0), auto_close_(true)
|
||||
{ this->set_true_eof(true); }
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::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<typename T, typename Tr>
|
||||
bool direct_streambuf<T, Tr>::is_open() const
|
||||
{ return ibeg_ != 0 || obeg_ != 0; }
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::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 T, typename Tr>
|
||||
typename direct_streambuf<T, Tr>::int_type
|
||||
direct_streambuf<T, Tr>::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 T, typename Tr>
|
||||
typename direct_streambuf<T, Tr>::int_type
|
||||
direct_streambuf<T, Tr>::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 T, typename Tr>
|
||||
typename direct_streambuf<T, Tr>::int_type
|
||||
direct_streambuf<T, Tr>::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<typename T, typename Tr>
|
||||
inline typename direct_streambuf<T, Tr>::pos_type
|
||||
direct_streambuf<T, Tr>::seekoff
|
||||
(off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
|
||||
{ return seek_impl(off, way, which); }
|
||||
|
||||
template<typename T, typename Tr>
|
||||
inline typename direct_streambuf<T, Tr>::pos_type
|
||||
direct_streambuf<T, Tr>::seekpos
|
||||
(pos_type sp, BOOST_IOS::openmode which)
|
||||
{
|
||||
return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which);
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::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 T, typename Tr>
|
||||
typename direct_streambuf<T, Tr>::pos_type direct_streambuf<T, Tr>::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<int>(next - (pptr() - obeg_)));
|
||||
result = next;
|
||||
}
|
||||
return offset_to_position(result);
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::init_input(input)
|
||||
{
|
||||
std::pair<char_type*, char_type*> p = input_sequence(*storage_);
|
||||
ibeg_ = p.first;
|
||||
iend_ = p.second;
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::init_output(output)
|
||||
{
|
||||
std::pair<char_type*, char_type*> p = output_sequence(*storage_);
|
||||
obeg_ = p.first;
|
||||
oend_ = p.second;
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::init_get_area()
|
||||
{
|
||||
setg(ibeg_, ibeg_, iend_);
|
||||
if (one_head() && pptr()) {
|
||||
gbump(static_cast<int>(pptr() - obeg_));
|
||||
setp(0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
void direct_streambuf<T, Tr>::init_put_area()
|
||||
{
|
||||
setp(obeg_, oend_);
|
||||
if (one_head() && gptr()) {
|
||||
pbump(static_cast<int>(gptr() - ibeg_));
|
||||
setg(0, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Tr>
|
||||
inline bool direct_streambuf<T, Tr>::one_head() const
|
||||
{ return ibeg_ && obeg_ && ibeg_ == obeg_; }
|
||||
|
||||
template<typename T, typename Tr>
|
||||
inline bool direct_streambuf<T, Tr>::two_head() const
|
||||
{ return ibeg_ && obeg_ && ibeg_ != obeg_; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_DIRECT_STREAMBUF_HPP_INCLUDED
|
454
boost/iostreams/detail/streambuf/indirect_streambuf.hpp
Normal file
454
boost/iostreams/detail/streambuf/indirect_streambuf.hpp
Normal file
@ -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 <algorithm> // min, max.
|
||||
#include <cassert>
|
||||
#include <exception>
|
||||
#include <boost/config.hpp> // Member template friends.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
#include <boost/iostreams/constants.hpp>
|
||||
#include <boost/iostreams/detail/adapter/concept_adapter.hpp>
|
||||
#include <boost/iostreams/detail/buffer.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/double_object.hpp>
|
||||
#include <boost/iostreams/detail/execute.hpp>
|
||||
#include <boost/iostreams/detail/functional.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/detail/optional.hpp>
|
||||
#include <boost/iostreams/detail/push.hpp>
|
||||
#include <boost/iostreams/detail/streambuf/linked_streambuf.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/iostreams/traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC, BCC 5.x
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
//
|
||||
// Description: The implementation of basic_streambuf used by chains.
|
||||
//
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
class indirect_streambuf
|
||||
: public linked_streambuf<BOOST_DEDUCED_TYPENAME char_type_of<T>::type, Tr>
|
||||
{
|
||||
public:
|
||||
typedef typename char_type_of<T>::type char_type;
|
||||
BOOST_IOSTREAMS_STREAMBUF_TYPEDEFS(Tr)
|
||||
private:
|
||||
typedef typename category_of<T>::type category;
|
||||
typedef concept_adapter<T> wrapper;
|
||||
typedef detail::basic_buffer<char_type, Alloc> buffer_type;
|
||||
typedef indirect_streambuf<T, Tr, Alloc, Mode> my_type;
|
||||
typedef detail::linked_streambuf<char_type, traits_type> base_type;
|
||||
typedef linked_streambuf<char_type, Tr> 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<Mode, input>::value; }
|
||||
bool can_write() const { return is_convertible<Mode, output>::value; }
|
||||
bool output_buffered() const { return (flags_ & f_output_buffered) != 0; }
|
||||
bool shared_buffer() const { return is_convertible<Mode, seekable>::value || is_convertible<Mode, dual_seekable>::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<wrapper> 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<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::indirect_streambuf()
|
||||
: next_(0), pback_size_(0), flags_(f_auto_close) { }
|
||||
|
||||
//--------------Implementation of open, is_open and close---------------------//
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::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<int>(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<int>(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<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
inline bool indirect_streambuf<T, Tr, Alloc, Mode>::is_open() const
|
||||
{ return (flags_ & f_open) != 0; }
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::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<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
bool indirect_streambuf<T, Tr, Alloc, Mode>::auto_close() const
|
||||
{ return (flags_ & f_auto_close) != 0; }
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::set_auto_close(bool close)
|
||||
{ flags_ = (flags_ & ~f_auto_close) | (close ? f_auto_close : 0); }
|
||||
|
||||
//--------------Implementation virtual functions------------------------------//
|
||||
|
||||
#ifndef BOOST_IOSTREAMS_NO_LOCALE
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::imbue(const std::locale& loc)
|
||||
{
|
||||
if (is_open()) {
|
||||
obj().imbue(loc);
|
||||
if (next_)
|
||||
next_->pubimbue(loc);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::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<std::streamsize>(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 T, typename Tr, typename Alloc, typename Mode>
|
||||
typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::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 T, typename Tr, typename Alloc, typename Mode>
|
||||
typename indirect_streambuf<T, Tr, Alloc, Mode>::int_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::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<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
int indirect_streambuf<T, Tr, Alloc, Mode>::sync()
|
||||
{
|
||||
try { // sync() is no-throw.
|
||||
sync_impl();
|
||||
obj().flush(next_);
|
||||
return 0;
|
||||
} catch (...) { return -1; }
|
||||
}
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
bool indirect_streambuf<T, Tr, Alloc, Mode>::strict_sync()
|
||||
{
|
||||
try { // sync() is no-throw.
|
||||
sync_impl();
|
||||
return obj().flush(next_);
|
||||
} catch (...) { return false; }
|
||||
}
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::seekoff
|
||||
(off_type off, BOOST_IOS::seekdir way, BOOST_IOS::openmode which)
|
||||
{ return seek_impl(off, way, which); }
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
inline typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::seekpos
|
||||
(pos_type sp, BOOST_IOS::openmode which)
|
||||
{
|
||||
return seek_impl(position_to_offset(sp), BOOST_IOS::beg, which);
|
||||
}
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
typename indirect_streambuf<T, Tr, Alloc, Mode>::pos_type
|
||||
indirect_streambuf<T, Tr, Alloc, Mode>::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<int>(off));
|
||||
return obj().seek(stream_offset(0), BOOST_IOS::cur, BOOST_IOS::in, next_) -
|
||||
static_cast<off_type>(egptr() - gptr());
|
||||
}
|
||||
if (pptr() != 0)
|
||||
this->BOOST_IOSTREAMS_PUBSYNC(); // sync() confuses VisualAge 6.
|
||||
if (way == BOOST_IOS::cur && gptr())
|
||||
off -= static_cast<off_type>(egptr() - gptr());
|
||||
bool two_head = is_convertible<category, dual_seekable>::value ||
|
||||
is_convertible<category, bidirectional_seekable>::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<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
inline void indirect_streambuf<T, Tr, Alloc, Mode>::set_next
|
||||
(streambuf_type* next)
|
||||
{ next_ = next; }
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
inline void indirect_streambuf<T, Tr, Alloc, Mode>::close_impl
|
||||
(BOOST_IOS::openmode which)
|
||||
{
|
||||
if (which == BOOST_IOS::in && is_convertible<Mode, input>::value) {
|
||||
setg(0, 0, 0);
|
||||
}
|
||||
if (which == BOOST_IOS::out && is_convertible<Mode, output>::value) {
|
||||
sync();
|
||||
setp(0, 0);
|
||||
}
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(push)
|
||||
#pragma warning(disable: 4127) // conditional expression is constant
|
||||
#endif
|
||||
if ( !is_convertible<category, dual_use>::value ||
|
||||
is_convertible<Mode, input>::value == (which == BOOST_IOS::in) )
|
||||
{
|
||||
obj().close(which, next_);
|
||||
}
|
||||
#if defined(BOOST_MSVC)
|
||||
#pragma warning(pop)
|
||||
#endif
|
||||
}
|
||||
|
||||
//----------State changing functions------------------------------------------//
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::sync_impl()
|
||||
{
|
||||
std::streamsize avail, amt;
|
||||
if ((avail = static_cast<std::streamsize>(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<int>(ptr - pptr()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::init_get_area()
|
||||
{
|
||||
if (shared_buffer() && pptr() != 0) {
|
||||
sync_impl();
|
||||
setp(0, 0);
|
||||
}
|
||||
setg(in().begin(), in().begin(), in().begin());
|
||||
}
|
||||
|
||||
template<typename T, typename Tr, typename Alloc, typename Mode>
|
||||
void indirect_streambuf<T, Tr, Alloc, Mode>::init_put_area()
|
||||
{
|
||||
using namespace std;
|
||||
if (shared_buffer() && gptr() != 0) {
|
||||
obj().seek(static_cast<off_type>(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 <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC, BCC 5.x
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_INDIRECT_STREAMBUF_HPP_INCLUDED
|
114
boost/iostreams/detail/streambuf/linked_streambuf.hpp
Normal file
114
boost/iostreams/detail/streambuf/linked_streambuf.hpp
Normal file
@ -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 <boost/config.hpp> // member template friends.
|
||||
#include <boost/core/typeinfo.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode.
|
||||
#include <boost/iostreams/detail/streambuf.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<typename Self, typename Ch, typename Tr, typename Alloc, typename Mode>
|
||||
class chain_base;
|
||||
|
||||
template<typename Chain, typename Access, typename Mode> 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<typename Ch, typename Tr = BOOST_IOSTREAMS_CHAR_TRAITS(Ch) >
|
||||
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<typename Chain, typename Mode, typename Access>
|
||||
friend class chainbuf;
|
||||
template<typename U>
|
||||
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<Ch, Tr>* /* 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 <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_LINKED_STREAMBUF_HPP_INCLUDED
|
84
boost/iostreams/detail/system_failure.hpp
Normal file
84
boost/iostreams/detail/system_failure.hpp
Normal file
@ -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 <cstring>
|
||||
#include <string>
|
||||
#include <boost/config.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // 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 <windows.h>
|
||||
#else
|
||||
# include <errno.h>
|
||||
# include <string.h>
|
||||
#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
|
26
boost/iostreams/detail/template_params.hpp
Normal file
26
boost/iostreams/detail/template_params.hpp
Normal file
@ -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 <boost/preprocessor/control/expr_if.hpp>
|
||||
#include <boost/preprocessor/control/if.hpp>
|
||||
#include <boost/preprocessor/repetition/enum_params.hpp>
|
||||
|
||||
#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
|
62
boost/iostreams/detail/translate_int_type.hpp
Normal file
62
boost/iostreams/detail/translate_int_type.hpp
Normal file
@ -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 <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
template<bool IsSame>
|
||||
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 SourceTr, typename TargetTr>
|
||||
typename TargetTr::int_type
|
||||
translate_int_type(typename SourceTr::int_type c)
|
||||
{
|
||||
typedef translate_int_type_impl<is_same<SourceTr, TargetTr>::value> impl;
|
||||
return impl::template inner<SourceTr, TargetTr>::translate(c);
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
template<>
|
||||
struct translate_int_type_impl<true> {
|
||||
template<typename SourceTr, typename TargetTr>
|
||||
struct inner {
|
||||
static typename TargetTr::int_type
|
||||
translate(typename SourceTr::int_type c) { return c; }
|
||||
};
|
||||
};
|
||||
|
||||
template<>
|
||||
struct translate_int_type_impl<false> {
|
||||
template<typename SourceTr, typename TargetTr>
|
||||
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
|
98
boost/iostreams/detail/wrap_unwrap.hpp
Normal file
98
boost/iostreams/detail/wrap_unwrap.hpp
Normal file
@ -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 <boost/config.hpp> // SFINAE, MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/detail/enable_if_stream.hpp>
|
||||
#include <boost/iostreams/traits_fwd.hpp> // is_std_io.
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/mpl/identity.hpp>
|
||||
#include <boost/mpl/eval_if.hpp>
|
||||
#include <boost/mpl/if.hpp>
|
||||
#include <boost/ref.hpp>
|
||||
|
||||
namespace boost { namespace iostreams { namespace detail {
|
||||
|
||||
//------------------Definition of wrap/unwrap traits--------------------------//
|
||||
|
||||
template<typename T>
|
||||
struct wrapped_type
|
||||
: mpl::if_<is_std_io<T>, reference_wrapper<T>, T>
|
||||
{ };
|
||||
|
||||
template<typename T>
|
||||
struct unwrapped_type
|
||||
: unwrap_reference<T>
|
||||
{ };
|
||||
|
||||
template<typename T>
|
||||
struct unwrap_ios
|
||||
: mpl::eval_if<
|
||||
is_std_io<T>,
|
||||
unwrap_reference<T>,
|
||||
mpl::identity<T>
|
||||
>
|
||||
{ };
|
||||
|
||||
//------------------Definition of wrap----------------------------------------//
|
||||
|
||||
#ifndef BOOST_NO_SFINAE //----------------------------------------------------//
|
||||
template<typename T>
|
||||
inline T wrap(const T& t BOOST_IOSTREAMS_DISABLE_IF_STREAM(T))
|
||||
{ return t; }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type
|
||||
wrap(T& t BOOST_IOSTREAMS_ENABLE_IF_STREAM(T)) { return boost::ref(t); }
|
||||
#else // #ifndef BOOST_NO_SFINAE //-------------------------------------------//
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
|
||||
wrap_impl(const T& t, mpl::true_) { return boost::ref(const_cast<T&>(t)); }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type // BCC 5.x needs namespace qualification.
|
||||
wrap_impl(T& t, mpl::true_) { return boost::ref(t); }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type
|
||||
wrap_impl(const T& t, mpl::false_) { return t; }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type
|
||||
wrap_impl(T& t, mpl::false_) { return t; }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type
|
||||
wrap(const T& t) { return wrap_impl(t, is_std_io<T>()); }
|
||||
|
||||
template<typename T>
|
||||
inline typename wrapped_type<T>::type
|
||||
wrap(T& t) { return wrap_impl(t, is_std_io<T>()); }
|
||||
#endif // #ifndef BOOST_NO_SFINAE //------------------------------------------//
|
||||
|
||||
//------------------Definition of unwrap--------------------------------------//
|
||||
|
||||
template<typename T>
|
||||
typename unwrapped_type<T>::type&
|
||||
unwrap(const reference_wrapper<T>& ref) { return ref.get(); }
|
||||
|
||||
template<typename T>
|
||||
typename unwrapped_type<T>::type& unwrap(T& t) { return t; }
|
||||
|
||||
template<typename T>
|
||||
const typename unwrapped_type<T>::type& unwrap(const T& t) { return t; }
|
||||
|
||||
} } } // End namespaces detail, iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_WRAP_UNWRAP_HPP_INCLUDED
|
133
boost/iostreams/device/array.hpp
Normal file
133
boost/iostreams/device/array.hpp
Normal file
@ -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/config.hpp> // BOOST_MSVC, make sure size_t is in std.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <cstddef> // std::size_t.
|
||||
#include <utility> // pair.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/preprocessor/cat.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
namespace detail {
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
class array_adapter {
|
||||
public:
|
||||
typedef Ch char_type;
|
||||
typedef std::pair<char_type*, char_type*> 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<int N>
|
||||
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<typename Ch> \
|
||||
struct BOOST_PP_CAT(basic_, name) : detail::array_adapter<mode, Ch> { \
|
||||
private: \
|
||||
typedef detail::array_adapter<mode, Ch> 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<int N> \
|
||||
BOOST_PP_CAT(basic_, name)(Ch (&ar)[N]) \
|
||||
: base_type(ar) { } \
|
||||
}; \
|
||||
typedef BOOST_PP_CAT(basic_, name)<char> name; \
|
||||
typedef BOOST_PP_CAT(basic_, name)<wchar_t> 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<typename Mode, typename Ch>
|
||||
array_adapter<Mode, Ch>::array_adapter
|
||||
(char_type* begin, char_type* end)
|
||||
: begin_(begin), end_(end)
|
||||
{ }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
array_adapter<Mode, Ch>::array_adapter
|
||||
(char_type* begin, std::size_t length)
|
||||
: begin_(begin), end_(begin + length)
|
||||
{ }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
array_adapter<Mode, Ch>::array_adapter
|
||||
(const char_type* begin, const char_type* end)
|
||||
: begin_(const_cast<char_type*>(begin)), // Treated as read-only.
|
||||
end_(const_cast<char_type*>(end)) // Treated as read-only.
|
||||
{ BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
array_adapter<Mode, Ch>::array_adapter
|
||||
(const char_type* begin, std::size_t length)
|
||||
: begin_(const_cast<char_type*>(begin)), // Treated as read-only.
|
||||
end_(const_cast<char_type*>(begin) + length) // Treated as read-only.
|
||||
{ BOOST_STATIC_ASSERT((!is_convertible<Mode, output>::value)); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
typename array_adapter<Mode, Ch>::pair_type
|
||||
array_adapter<Mode, Ch>::input_sequence()
|
||||
{ BOOST_STATIC_ASSERT((is_convertible<Mode, input>::value));
|
||||
return pair_type(begin_, end_); }
|
||||
|
||||
template<typename Mode, typename Ch>
|
||||
typename array_adapter<Mode, Ch>::pair_type
|
||||
array_adapter<Mode, Ch>::output_sequence()
|
||||
{ BOOST_STATIC_ASSERT((is_convertible<Mode, output>::value));
|
||||
return pair_type(begin_, end_); }
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_ARRAY_HPP_INCLUDED
|
41
boost/iostreams/device/back_inserter.hpp
Normal file
41
boost/iostreams/device/back_inserter.hpp
Normal file
@ -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 <boost/iostreams/detail/ios.hpp> // streamsize.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template<typename Container>
|
||||
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<typename Container>
|
||||
back_insert_device<Container> back_inserter(Container& cnt)
|
||||
{ return back_insert_device<Container>(cnt); }
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_BACK_INSERTER_HPP_INCLUDED
|
191
boost/iostreams/device/file.hpp
Normal file
191
boost/iostreams/device/file.hpp
Normal file
@ -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 <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#ifndef BOOST_IOSTREAMS_NO_LOCALE
|
||||
# include <locale>
|
||||
#endif
|
||||
#include <string> // pathnames, char_traits.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
|
||||
#include <boost/iostreams/detail/fstream.hpp>
|
||||
#include <boost/iostreams/operations.hpp> // seek.
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // MSVC.
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template<typename Ch>
|
||||
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<impl> pimpl_;
|
||||
};
|
||||
|
||||
typedef basic_file<char> file;
|
||||
typedef basic_file<wchar_t> wfile;
|
||||
|
||||
template<typename Ch>
|
||||
struct basic_file_source : private basic_file<Ch> {
|
||||
typedef Ch char_type;
|
||||
struct category
|
||||
: input_seekable,
|
||||
device_tag,
|
||||
closable_tag
|
||||
{ };
|
||||
using basic_file<Ch>::read;
|
||||
using basic_file<Ch>::putback;
|
||||
using basic_file<Ch>::seek;
|
||||
using basic_file<Ch>::is_open;
|
||||
using basic_file<Ch>::close;
|
||||
basic_file_source( const std::string& path,
|
||||
BOOST_IOS::openmode mode =
|
||||
BOOST_IOS::in )
|
||||
: basic_file<Ch>(path, mode & ~BOOST_IOS::out, BOOST_IOS::in)
|
||||
{ }
|
||||
void open( const std::string& path,
|
||||
BOOST_IOS::openmode mode = BOOST_IOS::in )
|
||||
{
|
||||
basic_file<Ch>::open(path, mode & ~BOOST_IOS::out, BOOST_IOS::in);
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_file_source<char> file_source;
|
||||
typedef basic_file_source<wchar_t> wfile_source;
|
||||
|
||||
template<typename Ch>
|
||||
struct basic_file_sink : private basic_file<Ch> {
|
||||
typedef Ch char_type;
|
||||
struct category
|
||||
: output_seekable,
|
||||
device_tag,
|
||||
closable_tag,
|
||||
flushable_tag
|
||||
{ };
|
||||
using basic_file<Ch>::write;
|
||||
using basic_file<Ch>::seek;
|
||||
using basic_file<Ch>::is_open;
|
||||
using basic_file<Ch>::close;
|
||||
using basic_file<Ch>::flush;
|
||||
basic_file_sink( const std::string& path,
|
||||
BOOST_IOS::openmode mode = BOOST_IOS::out )
|
||||
: basic_file<Ch>(path, mode & ~BOOST_IOS::in, BOOST_IOS::out)
|
||||
{ }
|
||||
void open( const std::string& path,
|
||||
BOOST_IOS::openmode mode = BOOST_IOS::out )
|
||||
{
|
||||
basic_file<Ch>::open(path, mode & ~BOOST_IOS::in, BOOST_IOS::out);
|
||||
}
|
||||
};
|
||||
|
||||
typedef basic_file_sink<char> file_sink;
|
||||
typedef basic_file_sink<wchar_t> wfile_sink;
|
||||
|
||||
//------------------Implementation of basic_file------------------------------//
|
||||
|
||||
template<typename Ch>
|
||||
basic_file<Ch>::basic_file
|
||||
( const std::string& path, BOOST_IOS::openmode mode,
|
||||
BOOST_IOS::openmode base_mode )
|
||||
{
|
||||
open(path, mode, base_mode);
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
inline std::streamsize basic_file<Ch>::read
|
||||
(char_type* s, std::streamsize n)
|
||||
{
|
||||
std::streamsize result = pimpl_->file_.sgetn(s, n);
|
||||
return result != 0 ? result : -1;
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
inline bool basic_file<Ch>::putback(char_type c)
|
||||
{
|
||||
return !!pimpl_->file_.sputbackc(c);
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
inline std::streamsize basic_file<Ch>::write
|
||||
(const char_type* s, std::streamsize n)
|
||||
{ return pimpl_->file_.sputn(s, n); }
|
||||
|
||||
template<typename Ch>
|
||||
std::streampos basic_file<Ch>::seek
|
||||
( stream_offset off, BOOST_IOS::seekdir way,
|
||||
BOOST_IOS::openmode )
|
||||
{ return iostreams::seek(pimpl_->file_, off, way); }
|
||||
|
||||
template<typename Ch>
|
||||
void basic_file<Ch>::open
|
||||
( const std::string& path, BOOST_IOS::openmode mode,
|
||||
BOOST_IOS::openmode base_mode )
|
||||
{
|
||||
pimpl_.reset(new impl(path, mode | base_mode));
|
||||
}
|
||||
|
||||
template<typename Ch>
|
||||
bool basic_file<Ch>::is_open() const { return pimpl_->file_.is_open(); }
|
||||
|
||||
template<typename Ch>
|
||||
void basic_file<Ch>::close() { pimpl_->file_.close(); }
|
||||
|
||||
template<typename Ch>
|
||||
bool basic_file<Ch>::flush()
|
||||
{ return pimpl_->file_.BOOST_IOSTREAMS_PUBSYNC() == 0; }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED
|
325
boost/iostreams/device/file_descriptor.hpp
Normal file
325
boost/iostreams/device/file_descriptor.hpp
Normal file
@ -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 <string>
|
||||
#include <boost/cstdint.hpp> // intmax_t.
|
||||
#include <boost/iostreams/categories.hpp> // tags.
|
||||
#include <boost/iostreams/detail/config/auto_link.hpp>
|
||||
#include <boost/iostreams/detail/config/dyn_link.hpp>
|
||||
#include <boost/iostreams/detail/config/windows_posix.hpp>
|
||||
#include <boost/iostreams/detail/file_handle.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, seekdir, int types.
|
||||
#include <boost/iostreams/detail/path.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
|
||||
// Must come last.
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4251) // Missing DLL interface for shared_ptr
|
||||
#endif
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
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<typename Path>
|
||||
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<typename Path>
|
||||
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<impl_type> 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<typename Path>
|
||||
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<typename Path>
|
||||
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<typename Path>
|
||||
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<typename Path>
|
||||
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 <boost/config/abi_suffix.hpp> // 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
|
609
boost/iostreams/device/mapped_file.hpp
Normal file
609
boost/iostreams/device/mapped_file.hpp
Normal file
@ -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 <boost/config.hpp> // make sure size_t is in std.
|
||||
#include <cstddef> // size_t.
|
||||
#include <string> // pathnames.
|
||||
#include <utility> // pair.
|
||||
#include <boost/config.hpp> // BOOST_MSVC.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/close.hpp>
|
||||
#include <boost/iostreams/concepts.hpp>
|
||||
#include <boost/iostreams/detail/config/auto_link.hpp>
|
||||
#include <boost/iostreams/detail/config/dyn_link.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, failure
|
||||
#include <boost/iostreams/detail/path.hpp>
|
||||
#include <boost/iostreams/operations_fwd.hpp>
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#include <boost/static_assert.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
// Must come last.
|
||||
#if defined(BOOST_MSVC)
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4251) // Missing DLL interface for shared_ptr
|
||||
#endif
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
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<mapped_file_base::mapmode>(0)),
|
||||
mode(), offset(0), length(static_cast<std::size_t>(-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<typename Path>
|
||||
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<Path, std::wstring>::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<typename PathT>
|
||||
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<typename PathT>
|
||||
basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
|
||||
: base_type(other), path(other.path)
|
||||
{ }
|
||||
|
||||
typedef Path path_type;
|
||||
Path path;
|
||||
};
|
||||
|
||||
typedef basic_mapped_file_params<std::string> 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<detail::path> param_type;
|
||||
friend class mapped_file;
|
||||
friend class detail::mapped_file_impl;
|
||||
friend struct boost::iostreams::operations<mapped_file_source>;
|
||||
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<size_type>(-1));
|
||||
|
||||
// Default constructor
|
||||
mapped_file_source();
|
||||
|
||||
// Constructor taking a parameters object
|
||||
template<typename Path>
|
||||
explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
// Constructor taking a list of parameters
|
||||
template<typename Path>
|
||||
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<typename Path>
|
||||
void open(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
template<typename Path>
|
||||
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<impl_type> 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<detail::path> param_type;
|
||||
friend struct boost::iostreams::operations<mapped_file >;
|
||||
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<typename Path>
|
||||
explicit mapped_file(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
// Constructor taking a list of parameters
|
||||
template<typename Path>
|
||||
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<typename Path>
|
||||
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<typename Path>
|
||||
void open(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
// open overload taking a list of parameters
|
||||
template<typename Path>
|
||||
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<typename Path>
|
||||
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<mapped_file_sink>;
|
||||
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<typename Path>
|
||||
explicit mapped_file_sink(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
// Constructor taking a list of parameters
|
||||
template<typename Path>
|
||||
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<typename Path>
|
||||
void open(const basic_mapped_file_params<Path>& p);
|
||||
|
||||
// open overload taking a list of parameters
|
||||
template<typename Path>
|
||||
void open( const Path& path,
|
||||
size_type length = max_length,
|
||||
boost::intmax_t offset = 0,
|
||||
mapmode flags = readwrite );
|
||||
};
|
||||
|
||||
//------------------Implementation of mapped_file_source----------------------//
|
||||
|
||||
template<typename Path>
|
||||
mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
|
||||
{ init(); open(p); }
|
||||
|
||||
template<typename Path>
|
||||
mapped_file_source::mapped_file_source(
|
||||
const Path& path, size_type length, boost::intmax_t offset)
|
||||
{ init(); open(path, length, offset); }
|
||||
|
||||
template<typename Path>
|
||||
void mapped_file_source::open(const basic_mapped_file_params<Path>& 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<typename Path>
|
||||
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<typename Path>
|
||||
mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
|
||||
{ open(p); }
|
||||
|
||||
template<typename Path>
|
||||
mapped_file::mapped_file(
|
||||
const Path& path, mapmode flags,
|
||||
size_type length, stream_offset offset )
|
||||
{ open(path, flags, length, offset); }
|
||||
|
||||
template<typename Path>
|
||||
mapped_file::mapped_file(
|
||||
const Path& path, BOOST_IOS::openmode mode,
|
||||
size_type length, stream_offset offset )
|
||||
{ open(path, mode, length, offset); }
|
||||
|
||||
template<typename Path>
|
||||
void mapped_file::open(const basic_mapped_file_params<Path>& p)
|
||||
{ delegate_.open_impl(p); }
|
||||
|
||||
template<typename Path>
|
||||
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<typename Path>
|
||||
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<char*>(delegate_.data()) : 0; }
|
||||
|
||||
inline mapped_file::iterator mapped_file::end() const
|
||||
{ return (flags() != readonly) ? data() + size() : 0; }
|
||||
|
||||
//------------------Implementation of mapped_file_sink------------------------//
|
||||
|
||||
template<typename Path>
|
||||
mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
|
||||
{ open(p); }
|
||||
|
||||
template<typename Path>
|
||||
mapped_file_sink::mapped_file_sink(
|
||||
const Path& path, size_type length,
|
||||
boost::intmax_t offset, mapmode flags )
|
||||
{ open(path, length, offset, flags); }
|
||||
|
||||
template<typename Path>
|
||||
void mapped_file_sink::open(const basic_mapped_file_params<Path>& 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<typename Path>
|
||||
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<mapped_file_source>
|
||||
: boost::iostreams::detail::close_impl<closable_tag>
|
||||
{
|
||||
static std::pair<char*, char*>
|
||||
input_sequence(mapped_file_source& src)
|
||||
{
|
||||
return std::make_pair( const_cast<char*>(src.begin()),
|
||||
const_cast<char*>(src.end()) );
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct operations<mapped_file>
|
||||
: boost::iostreams::detail::close_impl<closable_tag>
|
||||
{
|
||||
static std::pair<char*, char*>
|
||||
input_sequence(mapped_file& file)
|
||||
{
|
||||
return std::make_pair(file.begin(), file.end());
|
||||
}
|
||||
static std::pair<char*, char*>
|
||||
output_sequence(mapped_file& file)
|
||||
{
|
||||
return std::make_pair(file.begin(), file.end());
|
||||
}
|
||||
};
|
||||
|
||||
template<>
|
||||
struct operations<mapped_file_sink>
|
||||
: boost::iostreams::detail::close_impl<closable_tag>
|
||||
{
|
||||
static std::pair<char*, char*>
|
||||
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<mapped_file::mapmode>
|
||||
(static_cast<int>(a) | static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline mapped_file::mapmode
|
||||
operator&(mapped_file::mapmode a, mapped_file::mapmode b)
|
||||
{
|
||||
return static_cast<mapped_file::mapmode>
|
||||
(static_cast<int>(a) & static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline mapped_file::mapmode
|
||||
operator^(mapped_file::mapmode a, mapped_file::mapmode b)
|
||||
{
|
||||
return static_cast<mapped_file::mapmode>
|
||||
(static_cast<int>(a) ^ static_cast<int>(b));
|
||||
}
|
||||
|
||||
inline mapped_file::mapmode
|
||||
operator~(mapped_file::mapmode a)
|
||||
{
|
||||
return static_cast<mapped_file::mapmode>(~static_cast<int>(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 <boost/config/abi_suffix.hpp> // 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
|
66
boost/iostreams/device/null.hpp
Normal file
66
boost/iostreams/device/null.hpp
Normal file
@ -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 <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, streamsize.
|
||||
#include <boost/iostreams/positioning.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template<typename Ch, typename Mode>
|
||||
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<typename Ch>
|
||||
struct basic_null_source : private basic_null_device<Ch, input> {
|
||||
typedef Ch char_type;
|
||||
typedef source_tag category;
|
||||
using basic_null_device<Ch, input>::read;
|
||||
using basic_null_device<Ch, input>::close;
|
||||
};
|
||||
|
||||
typedef basic_null_source<char> null_source;
|
||||
typedef basic_null_source<wchar_t> wnull_source;
|
||||
|
||||
template<typename Ch>
|
||||
struct basic_null_sink : private basic_null_device<Ch, output> {
|
||||
typedef Ch char_type;
|
||||
typedef sink_tag category;
|
||||
using basic_null_device<Ch, output>::write;
|
||||
using basic_null_device<Ch, output>::close;
|
||||
};
|
||||
|
||||
typedef basic_null_sink<char> null_sink;
|
||||
typedef basic_null_sink<wchar_t> wnull_sink;
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_NULL_HPP_INCLUDED
|
168
boost/iostreams/filter/aggregate.hpp
Normal file
168
boost/iostreams/filter/aggregate.hpp
Normal file
@ -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 <algorithm> // copy, min.
|
||||
#include <boost/assert.hpp>
|
||||
#include <iterator> // back_inserter
|
||||
#include <vector>
|
||||
#include <boost/iostreams/constants.hpp> // default_device_buffer_size
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, streamsize.
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/read.hpp> // check_eof
|
||||
#include <boost/iostreams/write.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // 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<typename Ch, typename Alloc = std::allocator<Ch> >
|
||||
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<typename Source>
|
||||
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<std::streamsize>(data_.size() - ptr_));
|
||||
if (amt) {
|
||||
BOOST_IOSTREAMS_CHAR_TRAITS(char_type)::copy(s, &data_[ptr_], amt);
|
||||
ptr_ += amt;
|
||||
}
|
||||
return detail::check_eof(amt);
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
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<typename Sink>
|
||||
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<std::streamsize>(filtered.size())
|
||||
);
|
||||
} catch (...) {
|
||||
close_impl();
|
||||
throw;
|
||||
}
|
||||
close_impl();
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
typedef std::vector<Ch, Alloc> 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<typename Source>
|
||||
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<typename Sink>
|
||||
void do_write(Sink& sink, const char_type* s, std::streamsize n)
|
||||
{
|
||||
typedef typename iostreams::category_of<Sink>::type category;
|
||||
typedef is_convertible<category, output> can_write;
|
||||
do_write(sink, s, n, can_write());
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
void do_write(Sink& sink, const char_type* s, std::streamsize n, mpl::true_)
|
||||
{ iostreams::write(sink, s, n); }
|
||||
|
||||
template<typename Sink>
|
||||
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 <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_AGGREGATE_FILTER_HPP_INCLUDED
|
431
boost/iostreams/filter/bzip2.hpp
Normal file
431
boost/iostreams/filter/bzip2.hpp
Normal file
@ -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 <cassert>
|
||||
#include <memory> // allocator.
|
||||
#include <new> // bad_alloc.
|
||||
#include <boost/config.hpp> // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/constants.hpp> // buffer size.
|
||||
#include <boost/iostreams/detail/config/auto_link.hpp>
|
||||
#include <boost/iostreams/detail/config/bzip2.hpp>
|
||||
#include <boost/iostreams/detail/config/dyn_link.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
|
||||
#include <boost/iostreams/filter/symmetric.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
// Must come last.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4251 4231 4660)
|
||||
#endif
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
// 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<typename Alloc>
|
||||
struct bzip2_allocator_traits {
|
||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename Alloc::template rebind<char>::other type;
|
||||
#else
|
||||
typedef typename std::allocator_traits<Alloc>::template rebind_alloc<char> type;
|
||||
#endif
|
||||
#else
|
||||
typedef std::allocator<char> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template< typename Alloc,
|
||||
typename Base = // VC6 workaround (C2516)
|
||||
BOOST_DEDUCED_TYPENAME bzip2_allocator_traits<Alloc>::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<Base>::size_type size_type;
|
||||
#endif
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, custom =
|
||||
(!is_same<std::allocator<char>, Base>::value));
|
||||
typedef typename bzip2_allocator_traits<Alloc>::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<typename Alloc>
|
||||
void init( bool compress,
|
||||
bzip2_allocator<Alloc>& alloc )
|
||||
{
|
||||
bool custom = bzip2_allocator<Alloc>::custom;
|
||||
do_init( compress,
|
||||
custom ? bzip2_allocator<Alloc>::allocate : 0,
|
||||
custom ? bzip2_allocator<Alloc>::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<typename Alloc = std::allocator<char> >
|
||||
class bzip2_compressor_impl
|
||||
: public bzip2_base,
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
public
|
||||
#endif
|
||||
bzip2_allocator<Alloc>
|
||||
{
|
||||
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<typename Alloc = std::allocator<char> >
|
||||
class bzip2_decompressor_impl
|
||||
: public bzip2_base,
|
||||
#if BOOST_WORKAROUND(BOOST_BORLANDC, < 0x600)
|
||||
public
|
||||
#endif
|
||||
bzip2_allocator<Alloc>
|
||||
{
|
||||
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<typename Alloc = std::allocator<char> >
|
||||
struct basic_bzip2_compressor
|
||||
: symmetric_filter<detail::bzip2_compressor_impl<Alloc>, Alloc>
|
||||
{
|
||||
private:
|
||||
typedef detail::bzip2_compressor_impl<Alloc> impl_type;
|
||||
typedef symmetric_filter<impl_type, Alloc> 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<typename Alloc = std::allocator<char> >
|
||||
struct basic_bzip2_decompressor
|
||||
: symmetric_filter<detail::bzip2_decompressor_impl<Alloc>, Alloc>
|
||||
{
|
||||
private:
|
||||
typedef detail::bzip2_decompressor_impl<Alloc> impl_type;
|
||||
typedef symmetric_filter<impl_type, Alloc> 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<typename Alloc, typename Base>
|
||||
void* bzip2_allocator<Alloc, Base>::allocate(void* self, int items, int size)
|
||||
{
|
||||
size_type len = items * size;
|
||||
char* ptr =
|
||||
static_cast<allocator_type*>(self)->allocate
|
||||
(len + sizeof(size_type)
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
, (char*)0
|
||||
#endif
|
||||
);
|
||||
*reinterpret_cast<size_type*>(ptr) = len;
|
||||
return ptr + sizeof(size_type);
|
||||
}
|
||||
|
||||
template<typename Alloc, typename Base>
|
||||
void bzip2_allocator<Alloc, Base>::deallocate(void* self, void* address)
|
||||
{
|
||||
char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type);
|
||||
size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type);
|
||||
static_cast<allocator_type*>(self)->deallocate(ptr, len);
|
||||
}
|
||||
|
||||
//------------------Implementation of bzip2_compressor_impl-------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
bzip2_compressor_impl<Alloc>::bzip2_compressor_impl(const bzip2_params& p)
|
||||
: bzip2_base(p), eof_(false) { }
|
||||
|
||||
template<typename Alloc>
|
||||
bzip2_compressor_impl<Alloc>::~bzip2_compressor_impl()
|
||||
{ (void) bzip2_base::end(true, std::nothrow); }
|
||||
|
||||
template<typename Alloc>
|
||||
bool bzip2_compressor_impl<Alloc>::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<typename Alloc>
|
||||
void bzip2_compressor_impl<Alloc>::close()
|
||||
{
|
||||
try {
|
||||
end(true);
|
||||
} catch (...) {
|
||||
eof_ = false;
|
||||
throw;
|
||||
}
|
||||
eof_ = false;
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
inline void bzip2_compressor_impl<Alloc>::init()
|
||||
{ bzip2_base::init(true, static_cast<bzip2_allocator<Alloc>&>(*this)); }
|
||||
|
||||
//------------------Implementation of bzip2_decompressor_impl-----------------//
|
||||
|
||||
template<typename Alloc>
|
||||
bzip2_decompressor_impl<Alloc>::bzip2_decompressor_impl(bool small)
|
||||
: bzip2_base(bzip2_params(small)), eof_(false) { }
|
||||
|
||||
template<typename Alloc>
|
||||
bzip2_decompressor_impl<Alloc>::~bzip2_decompressor_impl()
|
||||
{ (void) bzip2_base::end(false, std::nothrow); }
|
||||
|
||||
template<typename Alloc>
|
||||
bool bzip2_decompressor_impl<Alloc>::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<typename Alloc>
|
||||
void bzip2_decompressor_impl<Alloc>::close()
|
||||
{
|
||||
try {
|
||||
end(false);
|
||||
} catch (...) {
|
||||
eof_ = false;
|
||||
throw;
|
||||
}
|
||||
eof_ = false;
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
inline void bzip2_decompressor_impl<Alloc>::init()
|
||||
{ bzip2_base::init(false, static_cast<bzip2_allocator<Alloc>&>(*this)); }
|
||||
} // End namespace detail.
|
||||
|
||||
//------------------Implementation of bzip2_decompressor----------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
basic_bzip2_compressor<Alloc>::basic_bzip2_compressor
|
||||
(const bzip2_params& p, std::streamsize buffer_size)
|
||||
: base_type(buffer_size, p)
|
||||
{ }
|
||||
|
||||
//------------------Implementation of bzip2_decompressor----------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
basic_bzip2_decompressor<Alloc>::basic_bzip2_decompressor
|
||||
(bool small, std::streamsize buffer_size)
|
||||
: base_type(buffer_size, small)
|
||||
{ }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/config/abi_suffix.hpp> // Pops abi_suffix.hpp pragmas.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_BZIP2_HPP_INCLUDED
|
82
boost/iostreams/filter/counter.hpp
Normal file
82
boost/iostreams/filter/counter.hpp
Normal file
@ -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 <algorithm> // count.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/char_traits.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // 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<typename Ch>
|
||||
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<typename Source>
|
||||
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<Ch>::newline());
|
||||
chars_ += result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
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<Ch>::newline());
|
||||
chars_ += result;
|
||||
return result;
|
||||
}
|
||||
private:
|
||||
int lines_;
|
||||
int chars_;
|
||||
};
|
||||
BOOST_IOSTREAMS_PIPABLE(basic_counter, 1)
|
||||
|
||||
|
||||
typedef basic_counter<char> counter;
|
||||
typedef basic_counter<wchar_t> wcounter;
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_COUNTER_HPP_INCLUDED
|
109
boost/iostreams/filter/grep.hpp
Normal file
109
boost/iostreams/filter/grep.hpp
Normal file
@ -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 <iostream>
|
||||
|
||||
#include <memory> // allocator.
|
||||
#include <boost/iostreams/char_traits.hpp>
|
||||
#include <boost/iostreams/filter/line.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
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<Ch>,
|
||||
typename Alloc = std::allocator<Ch> >
|
||||
class basic_grep_filter : public basic_line_filter<Ch, Alloc> {
|
||||
private:
|
||||
typedef basic_line_filter<Ch, Alloc> base_type;
|
||||
public:
|
||||
typedef typename base_type::char_type char_type;
|
||||
typedef typename base_type::category category;
|
||||
typedef char_traits<char_type> traits_type;
|
||||
typedef typename base_type::string_type string_type;
|
||||
typedef basic_regex<Ch, Tr> 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<typename Sink>
|
||||
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<char> grep_filter;
|
||||
typedef basic_grep_filter<wchar_t> wgrep_filter;
|
||||
|
||||
//------------------Implementation of basic_grep_filter-----------------------//
|
||||
|
||||
template<typename Ch, typename Tr, typename Alloc>
|
||||
basic_grep_filter<Ch, Tr, Alloc>::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
|
757
boost/iostreams/filter/gzip.hpp
Normal file
757
boost/iostreams/filter/gzip.hpp
Normal file
@ -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 <boost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE,
|
||||
// DINKUMWARE_STDLIB, __STL_CONFIG_H.
|
||||
#include <algorithm> // min.
|
||||
#include <boost/assert.hpp>
|
||||
#include <cstdio> // EOF.
|
||||
#include <cstddef> // size_t.
|
||||
#include <ctime> // std::time_t.
|
||||
#include <memory> // allocator.
|
||||
#include <boost/config.hpp> // Put size_t in std.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/cstdint.hpp> // uint8_t, uint32_t.
|
||||
#include <boost/iostreams/checked_operations.hpp>
|
||||
#include <boost/iostreams/constants.hpp> // buffer size.
|
||||
#include <boost/iostreams/detail/adapter/non_blocking_adapter.hpp>
|
||||
#include <boost/iostreams/detail/adapter/range_adapter.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
|
||||
#include <boost/iostreams/detail/error.hpp>
|
||||
#include <boost/iostreams/operations.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/filter/zlib.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/putback.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
|
||||
// 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<typename Alloc = std::allocator<char> >
|
||||
class basic_gzip_compressor : basic_zlib_compressor<Alloc> {
|
||||
private:
|
||||
typedef basic_zlib_compressor<Alloc> 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<typename Source>
|
||||
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<typename Sink>
|
||||
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
|
||||
{
|
||||
if (!(flags_ & f_header_done)) {
|
||||
std::streamsize amt =
|
||||
static_cast<std::streamsize>(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<typename Sink>
|
||||
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<typename Sink>
|
||||
static void write_long(long n, Sink& next, boost::mpl::true_)
|
||||
{
|
||||
boost::iostreams::put(next, static_cast<char>(0xFF & n));
|
||||
boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 8)));
|
||||
boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 16)));
|
||||
boost::iostreams::put(next, static_cast<char>(0xFF & (n >> 24)));
|
||||
}
|
||||
template<typename Sink>
|
||||
static void write_long(long, Sink&, boost::mpl::false_)
|
||||
{
|
||||
}
|
||||
template<typename Sink>
|
||||
static void write_long(long n, Sink& next)
|
||||
{
|
||||
typedef typename category_of<Sink>::type category;
|
||||
typedef is_convertible<category, output> 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<typename Alloc = std::allocator<char> >
|
||||
class basic_gzip_decompressor : basic_zlib_decompressor<Alloc> {
|
||||
private:
|
||||
typedef basic_zlib_decompressor<Alloc> 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<typename Sink>
|
||||
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<typename Source>
|
||||
std::streamsize read(Source& src, char_type* s, std::streamsize n)
|
||||
{
|
||||
typedef char_traits<char> traits_type;
|
||||
std::streamsize result = 0;
|
||||
peekable_source<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<typename Source>
|
||||
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<typename Source>
|
||||
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<std::streamsize>(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<std::streamsize>(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<typename Alloc>
|
||||
basic_gzip_compressor<Alloc>::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<char>(gzip::magic::id2); // ID2.
|
||||
header_ += gzip::method::deflate; // CM.
|
||||
header_ += static_cast<char>(flags); // FLG.
|
||||
header_ += static_cast<char>(0xFF & p.mtime); // MTIME.
|
||||
header_ += static_cast<char>(0xFF & (p.mtime >> 8));
|
||||
header_ += static_cast<char>(0xFF & (p.mtime >> 16));
|
||||
header_ += static_cast<char>(0xFF & (p.mtime >> 24));
|
||||
header_ += static_cast<char>(extra_flags); // XFL.
|
||||
header_ += static_cast<char>(gzip::os_unknown); // OS.
|
||||
if (has_name) {
|
||||
header_ += p.file_name;
|
||||
header_ += '\0';
|
||||
}
|
||||
if (has_comment) {
|
||||
header_ += p.comment;
|
||||
header_ += '\0';
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
gzip_params basic_gzip_compressor<Alloc>::normalize_params(gzip_params p)
|
||||
{
|
||||
p.noheader = true;
|
||||
p.calculate_crc = true;
|
||||
return p;
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
void basic_gzip_compressor<Alloc>::prepare_footer()
|
||||
{
|
||||
boost::iostreams::back_insert_device<std::string> out(footer_);
|
||||
write_long(this->crc(), out);
|
||||
write_long(this->total_in(), out);
|
||||
flags_ |= f_body_done;
|
||||
offset_ = 0;
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
std::streamsize basic_gzip_compressor<Alloc>::read_string
|
||||
(char* s, std::streamsize n, std::string& str)
|
||||
{
|
||||
std::streamsize avail =
|
||||
static_cast<std::streamsize>(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<std::size_t>(str.size()) )
|
||||
{
|
||||
flags_ |= f_header_done;
|
||||
}
|
||||
return amt;
|
||||
}
|
||||
|
||||
//------------------Implementation of gzip_decompressor-----------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
|
||||
(int window_bits, std::streamsize buffer_size)
|
||||
: base_type(make_params(window_bits), buffer_size),
|
||||
state_(s_start)
|
||||
{ }
|
||||
|
||||
template<typename Alloc>
|
||||
gzip_params basic_gzip_decompressor<Alloc>::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
|
221
boost/iostreams/filter/line.hpp
Normal file
221
boost/iostreams/filter/line.hpp
Normal file
@ -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 <algorithm> // min.
|
||||
#include <boost/assert.hpp>
|
||||
#include <memory> // allocator.
|
||||
#include <string>
|
||||
#include <boost/config.hpp> // BOOST_STATIC_CONSTANT.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/checked_operations.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // openmode, streamsize.
|
||||
#include <boost/iostreams/read.hpp> // check_eof
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/write.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp> // 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<Ch> >
|
||||
class basic_line_filter {
|
||||
private:
|
||||
typedef typename std::basic_string<Ch>::traits_type string_traits;
|
||||
public:
|
||||
typedef Ch char_type;
|
||||
typedef char_traits<char_type> 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<typename Source>
|
||||
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<typename Sink>
|
||||
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<std::streamsize>(cur - s);
|
||||
} else {
|
||||
cur_line_.append(cur, rest);
|
||||
return n;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
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<std::streamsize>(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 Source>
|
||||
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<typename Sink>
|
||||
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<std::streamsize>(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<char> line_filter;
|
||||
typedef basic_line_filter<wchar_t> wline_filter;
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_LINE_FILTER_HPP_INCLUDED
|
376
boost/iostreams/filter/lzma.hpp
Normal file
376
boost/iostreams/filter/lzma.hpp
Normal file
@ -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 <cassert>
|
||||
#include <iosfwd> // streamsize.
|
||||
#include <memory> // allocator, bad_alloc.
|
||||
#include <new>
|
||||
#include <boost/config.hpp> // MSVC, STATIC_CONSTANT, DEDUCED_TYPENAME, DINKUM.
|
||||
#include <boost/detail/workaround.hpp>
|
||||
#include <boost/iostreams/constants.hpp> // buffer size.
|
||||
#include <boost/iostreams/detail/config/auto_link.hpp>
|
||||
#include <boost/iostreams/detail/config/dyn_link.hpp>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // failure, streamsize.
|
||||
#include <boost/iostreams/filter/symmetric.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/type_traits/is_same.hpp>
|
||||
|
||||
// Must come last.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(push)
|
||||
# pragma warning(disable:4251 4231 4660) // Dependencies not exported.
|
||||
#endif
|
||||
#include <boost/config/abi_prefix.hpp>
|
||||
|
||||
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<typename Alloc>
|
||||
struct lzma_allocator_traits {
|
||||
#ifndef BOOST_NO_STD_ALLOCATOR
|
||||
#if defined(BOOST_NO_CXX11_ALLOCATOR)
|
||||
typedef typename Alloc::template rebind<char>::other type;
|
||||
#else
|
||||
typedef typename std::allocator_traits<Alloc>::template rebind_alloc<char> type;
|
||||
#endif
|
||||
#else
|
||||
typedef std::allocator<char> type;
|
||||
#endif
|
||||
};
|
||||
|
||||
template< typename Alloc,
|
||||
typename Base = // VC6 workaround (C2516)
|
||||
BOOST_DEDUCED_TYPENAME lzma_allocator_traits<Alloc>::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<Base>::size_type size_type;
|
||||
#endif
|
||||
public:
|
||||
BOOST_STATIC_CONSTANT(bool, custom =
|
||||
(!is_same<std::allocator<char>, Base>::value));
|
||||
typedef typename lzma_allocator_traits<Alloc>::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<typename Alloc>
|
||||
void init( const lzma_params& p,
|
||||
bool compress,
|
||||
lzma_allocator<Alloc>& zalloc )
|
||||
{
|
||||
bool custom = lzma_allocator<Alloc>::custom;
|
||||
do_init( p, compress,
|
||||
custom ? lzma_allocator<Alloc>::allocate : 0,
|
||||
custom ? lzma_allocator<Alloc>::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<typename Alloc = std::allocator<char> >
|
||||
class lzma_compressor_impl : public lzma_base, public lzma_allocator<Alloc> {
|
||||
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<typename Alloc = std::allocator<char> >
|
||||
class lzma_decompressor_impl : public lzma_base, public lzma_allocator<Alloc> {
|
||||
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<typename Alloc = std::allocator<char> >
|
||||
struct basic_lzma_compressor
|
||||
: symmetric_filter<detail::lzma_compressor_impl<Alloc>, Alloc>
|
||||
{
|
||||
private:
|
||||
typedef detail::lzma_compressor_impl<Alloc> impl_type;
|
||||
typedef symmetric_filter<impl_type, Alloc> 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<typename Alloc = std::allocator<char> >
|
||||
struct basic_lzma_decompressor
|
||||
: symmetric_filter<detail::lzma_decompressor_impl<Alloc>, Alloc>
|
||||
{
|
||||
private:
|
||||
typedef detail::lzma_decompressor_impl<Alloc> impl_type;
|
||||
typedef symmetric_filter<impl_type, Alloc> 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<typename Alloc, typename Base>
|
||||
void* lzma_allocator<Alloc, Base>::allocate
|
||||
(void* self, size_t items, size_t size)
|
||||
{
|
||||
size_type len = items * size;
|
||||
char* ptr =
|
||||
static_cast<allocator_type*>(self)->allocate
|
||||
(len + sizeof(size_type)
|
||||
#if BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1)
|
||||
, (char*)0
|
||||
#endif
|
||||
);
|
||||
*reinterpret_cast<size_type*>(ptr) = len;
|
||||
return ptr + sizeof(size_type);
|
||||
}
|
||||
|
||||
template<typename Alloc, typename Base>
|
||||
void lzma_allocator<Alloc, Base>::deallocate(void* self, void* address)
|
||||
{
|
||||
char* ptr = reinterpret_cast<char*>(address) - sizeof(size_type);
|
||||
size_type len = *reinterpret_cast<size_type*>(ptr) + sizeof(size_type);
|
||||
static_cast<allocator_type*>(self)->deallocate(ptr, len);
|
||||
}
|
||||
|
||||
//------------------Implementation of lzma_compressor_impl--------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
lzma_compressor_impl<Alloc>::lzma_compressor_impl(const lzma_params& p)
|
||||
{ init(p, true, static_cast<lzma_allocator<Alloc>&>(*this)); }
|
||||
|
||||
template<typename Alloc>
|
||||
lzma_compressor_impl<Alloc>::~lzma_compressor_impl()
|
||||
{ reset(true, false); }
|
||||
|
||||
template<typename Alloc>
|
||||
bool lzma_compressor_impl<Alloc>::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<typename Alloc>
|
||||
void lzma_compressor_impl<Alloc>::close() { reset(true, true); }
|
||||
|
||||
//------------------Implementation of lzma_decompressor_impl------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
lzma_decompressor_impl<Alloc>::lzma_decompressor_impl(const lzma_params& p)
|
||||
{ init(p, false, static_cast<lzma_allocator<Alloc>&>(*this)); }
|
||||
|
||||
template<typename Alloc>
|
||||
lzma_decompressor_impl<Alloc>::~lzma_decompressor_impl()
|
||||
{ reset(false, false); }
|
||||
|
||||
template<typename Alloc>
|
||||
lzma_decompressor_impl<Alloc>::lzma_decompressor_impl()
|
||||
{
|
||||
lzma_params p;
|
||||
init(p, false, static_cast<lzma_allocator<Alloc>&>(*this));
|
||||
}
|
||||
|
||||
template<typename Alloc>
|
||||
bool lzma_decompressor_impl<Alloc>::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<typename Alloc>
|
||||
void lzma_decompressor_impl<Alloc>::close() { reset(false, true); }
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
//------------------Implementation of lzma_compressor-----------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
basic_lzma_compressor<Alloc>::basic_lzma_compressor
|
||||
(const lzma_params& p, std::streamsize buffer_size)
|
||||
: base_type(buffer_size, p) { }
|
||||
|
||||
//------------------Implementation of lzma_decompressor-----------------------//
|
||||
|
||||
template<typename Alloc>
|
||||
basic_lzma_decompressor<Alloc>::basic_lzma_decompressor
|
||||
(std::streamsize buffer_size)
|
||||
: base_type(buffer_size) { }
|
||||
|
||||
template<typename Alloc>
|
||||
basic_lzma_decompressor<Alloc>::basic_lzma_decompressor
|
||||
(const lzma_params& p, std::streamsize buffer_size)
|
||||
: base_type(buffer_size, p) { }
|
||||
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#include <boost/config/abi_suffix.hpp> // Pops abi_suffix.hpp pragmas.
|
||||
#ifdef BOOST_MSVC
|
||||
# pragma warning(pop)
|
||||
#endif
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_LZMA_HPP_INCLUDED
|
441
boost/iostreams/filter/newline.hpp
Normal file
441
boost/iostreams/filter/newline.hpp
Normal file
@ -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 <boost/assert.hpp>
|
||||
#include <cstdio>
|
||||
#include <stdexcept> // logic_error.
|
||||
#include <boost/config.hpp> // BOOST_STATIC_CONSTANT.
|
||||
#include <boost/iostreams/categories.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp> // BOOST_IOSTREAMS_FAILURE
|
||||
#include <boost/iostreams/read.hpp> // get
|
||||
#include <boost/iostreams/write.hpp> // put
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/putback.hpp>
|
||||
#include <boost/mpl/bool.hpp>
|
||||
#include <boost/throw_exception.hpp>
|
||||
#include <boost/type_traits/is_convertible.hpp>
|
||||
|
||||
// Must come last.
|
||||
#include <boost/iostreams/detail/config/disable_warnings.hpp>
|
||||
|
||||
#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<typename Source>
|
||||
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<typename Sink>
|
||||
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<typename Sink>
|
||||
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<typename Sink>
|
||||
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<typename Device>
|
||||
void newline_if_sink(Device& dest)
|
||||
{
|
||||
typedef typename iostreams::category_of<Device>::type category;
|
||||
newline_if_sink(dest, is_convertible<category, output>());
|
||||
}
|
||||
|
||||
template<typename Sink>
|
||||
void newline_if_sink(Sink& dest, mpl::true_) { newline(dest); }
|
||||
|
||||
template<typename Source>
|
||||
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<typename Source>
|
||||
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<typename Sink>
|
||||
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<typename Sink>
|
||||
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 <boost/iostreams/detail/config/enable_warnings.hpp>
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_NEWLINE_FILTER_HPP_INCLUDED
|
98
boost/iostreams/filter/regex.hpp
Normal file
98
boost/iostreams/filter/regex.hpp
Normal file
@ -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 <memory> // allocator.
|
||||
#include <boost/function.hpp>
|
||||
#include <boost/iostreams/filter/aggregate.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/regex.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
template< typename Ch,
|
||||
typename Tr = regex_traits<Ch>,
|
||||
typename Alloc = std::allocator<Ch> >
|
||||
class basic_regex_filter : public aggregate_filter<Ch, Alloc> {
|
||||
private:
|
||||
typedef aggregate_filter<Ch, Alloc> base_type;
|
||||
public:
|
||||
typedef typename base_type::char_type char_type;
|
||||
typedef typename base_type::category category;
|
||||
typedef std::basic_string<Ch> string_type;
|
||||
typedef basic_regex<Ch, Tr> regex_type;
|
||||
typedef regex_constants::match_flag_type flag_type;
|
||||
typedef match_results<const Ch*> match_type;
|
||||
typedef function1<string_type, const match_type&> 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<const Ch*, Ch, Tr> 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<char> regex_filter;
|
||||
typedef basic_regex_filter<wchar_t> wregex_filter;
|
||||
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_REGEX_FILTER_HPP_INCLUDED
|
84
boost/iostreams/filter/stdio.hpp
Normal file
84
boost/iostreams/filter/stdio.hpp
Normal file
@ -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 <iostream>
|
||||
#include <memory> // allocator.
|
||||
#include <vector>
|
||||
#include <boost/iostreams/detail/config/wide_streams.hpp>
|
||||
#include <boost/iostreams/detail/char_traits.hpp>
|
||||
#include <boost/iostreams/detail/ios.hpp>
|
||||
#include <boost/iostreams/device/array.hpp>
|
||||
#include <boost/iostreams/device/back_inserter.hpp>
|
||||
#include <boost/iostreams/filter/aggregate.hpp>
|
||||
#include <boost/iostreams/pipeline.hpp>
|
||||
#include <boost/iostreams/stream_buffer.hpp>
|
||||
|
||||
namespace boost { namespace iostreams {
|
||||
|
||||
namespace detail {
|
||||
|
||||
} // End namespace detail.
|
||||
|
||||
template<typename Ch, typename Alloc = std::allocator<Ch> >
|
||||
class basic_stdio_filter : public aggregate_filter<Ch, Alloc> {
|
||||
private:
|
||||
typedef aggregate_filter<Ch, Alloc> 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<Ch> >
|
||||
srcbuf(&src[0], &src[0] + src.size());
|
||||
stream_buffer< back_insert_device<vector_type> >
|
||||
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<char> stdio_filter;
|
||||
typedef basic_stdio_filter<wchar_t> wstdio_wfilter;
|
||||
|
||||
} } // End namespaces iostreams, boost.
|
||||
|
||||
#endif // #ifndef BOOST_IOSTREAMS_STDIO_FILTER_HPP_INCLUDED
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user