|
Boost-Commit : |
Subject: [Boost-commit] svn:boost r56830 - in branches/release: boost/iostreams boost/iostreams/detail boost/iostreams/detail/adapter boost/iostreams/detail/broken_overload_resolution boost/iostreams/detail/config boost/iostreams/detail/streambuf boost/iostreams/device boost/iostreams/filter libs/iostreams libs/iostreams/build libs/iostreams/doc libs/iostreams/doc/classes libs/iostreams/doc/functions libs/iostreams/example libs/iostreams/src libs/iostreams/test libs/iostreams/test/detail
From: bdawes_at_[hidden]
Date: 2009-10-14 11:20:44
Author: bemandawes
Date: 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
New Revision: 56830
URL: http://svn.boost.org/trac/boost/changeset/56830
Log:
iostreams: merge trunk per Jonathan
Added:
branches/release/boost/iostreams/detail/file_handle.hpp (contents, props changed)
branches/release/boost/iostreams/detail/path.hpp (contents, props changed)
branches/release/boost/iostreams/filter/grep.hpp (contents, props changed)
branches/release/libs/iostreams/CMakeLists.txt
- copied unchanged from r56828, /trunk/libs/iostreams/CMakeLists.txt
branches/release/libs/iostreams/doc/classes/grep_filter.html (contents, props changed)
branches/release/libs/iostreams/doc/functions/slice.html
- copied unchanged from r56828, /trunk/libs/iostreams/doc/functions/slice.html
branches/release/libs/iostreams/module.cmake
- copied unchanged from r56828, /trunk/libs/iostreams/module.cmake
branches/release/libs/iostreams/src/CMakeLists.txt
- copied unchanged from r56828, /trunk/libs/iostreams/src/CMakeLists.txt
branches/release/libs/iostreams/src/file_times.cpp (contents, props changed)
branches/release/libs/iostreams/src/gzip.cpp (contents, props changed)
branches/release/libs/iostreams/test/CMakeLists.txt
- copied unchanged from r56828, /trunk/libs/iostreams/test/CMakeLists.txt
branches/release/libs/iostreams/test/bool_trait_test.cpp (contents, props changed)
branches/release/libs/iostreams/test/grep_test.cpp (contents, props changed)
Properties modified:
branches/release/boost/iostreams/ (props changed)
branches/release/boost/iostreams/detail/execute.hpp (props changed)
branches/release/boost/iostreams/detail/functional.hpp (props changed)
branches/release/libs/iostreams/ (props changed)
Text files modified:
branches/release/boost/iostreams/chain.hpp | 12
branches/release/boost/iostreams/close.hpp | 1
branches/release/boost/iostreams/code_converter.hpp | 12
branches/release/boost/iostreams/combine.hpp | 19
branches/release/boost/iostreams/compose.hpp | 4
branches/release/boost/iostreams/detail/adapter/mode_adapter.hpp | 6
branches/release/boost/iostreams/detail/broken_overload_resolution/stream.hpp | 1
branches/release/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp | 1
branches/release/boost/iostreams/detail/buffer.hpp | 5
branches/release/boost/iostreams/detail/codecvt_helper.hpp | 5
branches/release/boost/iostreams/detail/config/disable_warnings.hpp | 3
branches/release/boost/iostreams/detail/config/rtl.hpp | 4
branches/release/boost/iostreams/detail/current_directory.hpp | 5
branches/release/boost/iostreams/detail/forward.hpp | 58 ++-
branches/release/boost/iostreams/detail/is_iterator_range.hpp | 7
branches/release/boost/iostreams/detail/restrict_impl.hpp | 6
branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp | 2
branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp | 4
branches/release/boost/iostreams/device/file.hpp | 16
branches/release/boost/iostreams/device/file_descriptor.hpp | 240 +++++++++----
branches/release/boost/iostreams/device/mapped_file.hpp | 562 +++++++++++++++++++++++++-------
branches/release/boost/iostreams/filter/gzip.hpp | 367 ++++++++++++--------
branches/release/boost/iostreams/filter/line.hpp | 37 +
branches/release/boost/iostreams/filter/newline.hpp | 4
branches/release/boost/iostreams/filter/symmetric.hpp | 10
branches/release/boost/iostreams/filter/zlib.hpp | 17
branches/release/boost/iostreams/invert.hpp | 1
branches/release/boost/iostreams/skip.hpp | 4
branches/release/boost/iostreams/stream.hpp | 1
branches/release/boost/iostreams/stream_buffer.hpp | 1
branches/release/boost/iostreams/tee.hpp | 115 ++++--
branches/release/boost/iostreams/traits.hpp | 31 +
branches/release/libs/iostreams/build/Jamfile.v2 | 2
branches/release/libs/iostreams/doc/bibliography.html | 4
branches/release/libs/iostreams/doc/classes/bzip2.html | 1
branches/release/libs/iostreams/doc/classes/regex_filter.html | 22
branches/release/libs/iostreams/doc/menu.html | 4
branches/release/libs/iostreams/doc/quick_reference.html | 11
branches/release/libs/iostreams/example/container_device.hpp | 6
branches/release/libs/iostreams/src/file_descriptor.cpp | 403 +++++++++++++++++-----
branches/release/libs/iostreams/src/mapped_file.cpp | 696 ++++++++++++++++++++-------------------
branches/release/libs/iostreams/src/zlib.cpp | 6
branches/release/libs/iostreams/test/Jamfile.v2 | 3
branches/release/libs/iostreams/test/component_access_test.cpp | 2
branches/release/libs/iostreams/test/detail/closable.hpp | 12
branches/release/libs/iostreams/test/detail/operation_sequence.hpp | 4
branches/release/libs/iostreams/test/gzip_test.cpp | 65 +++
branches/release/libs/iostreams/test/mapped_file_test.cpp | 172 +++++++--
branches/release/libs/iostreams/test/tee_test.cpp | 60 +++
49 files changed, 2041 insertions(+), 993 deletions(-)
Modified: branches/release/boost/iostreams/chain.hpp
==============================================================================
--- branches/release/boost/iostreams/chain.hpp (original)
+++ branches/release/boost/iostreams/chain.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -140,6 +140,10 @@
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
@@ -225,9 +229,9 @@
void push_impl(const T& t, int buffer_size = -1, int pback_size = -1)
{
typedef typename iostreams::category_of<T>::type category;
- typedef typename unwrap_ios<T>::type policy_type;
+ typedef typename unwrap_ios<T>::type component_type;
typedef stream_buffer<
- policy_type,
+ component_type,
BOOST_IOSTREAMS_CHAR_TRAITS(char_type),
Alloc, Mode
> streambuf_t;
@@ -248,7 +252,7 @@
buf(new streambuf_t(t, buffer_size, pback_size));
list().push_back(buf.get());
buf.release();
- if (is_device<policy_type>::value) {
+ if (is_device<component_type>::value) {
pimpl_->flags_ |= f_complete | f_open;
for ( iterator first = list().begin(),
last = list().end();
@@ -408,7 +412,7 @@
typedef typename traits_type::int_type int_type; \
typedef typename traits_type::off_type off_type; \
name_() { } \
- name_(const name_& rhs) { *this = rhs; } \
+ name_(const name_& rhs) : base_type(rhs) { } \
name_& operator=(const name_& rhs) \
{ base_type::operator=(rhs); return *this; } \
}; \
Modified: branches/release/boost/iostreams/close.hpp
==============================================================================
--- branches/release/boost/iostreams/close.hpp (original)
+++ branches/release/boost/iostreams/close.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -212,7 +212,6 @@
}
};
-#include <boost/iostreams/detail/config/disable_warnings.hpp> // Borland.
template<>
struct close_impl<closable_tag> {
template<typename T>
Modified: branches/release/boost/iostreams/code_converter.hpp
==============================================================================
--- branches/release/boost/iostreams/code_converter.hpp (original)
+++ branches/release/boost/iostreams/code_converter.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -138,8 +138,8 @@
is_direct<Device>,
direct_adapter<Device>,
Device
- >::type policy_type;
- typedef optional< concept_adapter<policy_type> > storage_type;
+ >::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;
@@ -168,7 +168,7 @@
buf_.second().resize(buffer_size);
buf_.second().set(0, 0);
}
- dev_.reset(concept_adapter<policy_type>(dev));
+ dev_.reset(concept_adapter<device_type>(dev));
flags_ = f_open;
}
@@ -200,7 +200,7 @@
bool is_open() const { return (flags_ & f_open) != 0;}
- policy_type& dev() { return **dev_; }
+ device_type& dev() { return **dev_; }
enum flag_type {
f_open = 1,
@@ -243,7 +243,7 @@
typedef detail::code_converter_impl<
Device, Codecvt, Alloc
> impl_type;
- typedef typename impl_type::policy_type policy_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;
@@ -298,7 +298,7 @@
}
const codecvt_type& cvt() { return impl().cvt_.get(); }
- policy_type& dev() { return impl().dev(); }
+ 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_; }
Modified: branches/release/boost/iostreams/combine.hpp
==============================================================================
--- branches/release/boost/iostreams/combine.hpp (original)
+++ branches/release/boost/iostreams/combine.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -45,6 +45,10 @@
//
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
@@ -53,6 +57,11 @@
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);
@@ -61,8 +70,6 @@
void imbue(const std::locale& loc);
#endif
private:
- typedef typename char_type_of<Sink>::type sink_char_type;
- BOOST_STATIC_ASSERT((is_same<char_type, sink_char_type>::value));
Source src_;
Sink sink_;
};
@@ -81,6 +88,7 @@
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
@@ -88,6 +96,11 @@
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>
@@ -120,8 +133,6 @@
void imbue(const std::locale& loc);
#endif
private:
- typedef typename char_type_of<OutputFilter>::type output_char_type;
- BOOST_STATIC_ASSERT((is_same<char_type, output_char_type>::value));
InputFilter in_;
OutputFilter out_;
};
Modified: branches/release/boost/iostreams/compose.hpp
==============================================================================
--- branches/release/boost/iostreams/compose.hpp (original)
+++ branches/release/boost/iostreams/compose.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -74,6 +74,8 @@
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
@@ -140,6 +142,8 @@
!(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
Modified: branches/release/boost/iostreams/detail/adapter/mode_adapter.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/adapter/mode_adapter.hpp (original)
+++ branches/release/boost/iostreams/detail/adapter/mode_adapter.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -31,7 +31,7 @@
private:
struct empty_base { };
public:
- typedef typename wrapped_type<T>::type policy_type;
+ typedef typename wrapped_type<T>::type component_type;
typedef typename char_type_of<T>::type char_type;
struct category
: Mode,
@@ -43,7 +43,7 @@
#endif
localizable_tag
{ };
- explicit mode_adapter(const policy_type& t) : t_(t) { }
+ explicit mode_adapter(const component_type& t) : t_(t) { }
// Device member functions.
@@ -88,7 +88,7 @@
void imbue(const Locale& loc)
{ iostreams::imbue(t_, loc); }
private:
- policy_type t_;
+ component_type t_;
};
//------------------Implementation of mode_adapter----------------------------//
Modified: branches/release/boost/iostreams/detail/broken_overload_resolution/stream.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/broken_overload_resolution/stream.hpp (original)
+++ branches/release/boost/iostreams/detail/broken_overload_resolution/stream.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -35,7 +35,6 @@
detail::stream_traits<
Device, Tr
>::stream_type stream_type;
- typedef Device policy_type;
public:
stream() { }
template<typename U0>
Modified: branches/release/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp (original)
+++ branches/release/boost/iostreams/detail/broken_overload_resolution/stream_buffer.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -35,7 +35,6 @@
detail::stream_buffer_traits<
T, Tr, Alloc, Mode
>::type base_type;
- typedef T policy_type;
public:
typedef typename char_type_of<T>::type char_type;
struct category
Modified: branches/release/boost/iostreams/detail/buffer.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/buffer.hpp (original)
+++ branches/release/boost/iostreams/detail/buffer.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -104,11 +104,6 @@
iostreams::read(src, this->data() + keep, this->size() - keep);
if (result != -1)
this->set(0, keep + result);
- //return result == this->size() - keep ?
- // traits_type::good() :
- // keep == -1 ?
- // traits_type::eof() :
- // traits_type::would_block();
return result == -1 ?
traits_type::eof() :
result == 0 ?
Modified: branches/release/boost/iostreams/detail/codecvt_helper.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/codecvt_helper.hpp (original)
+++ branches/release/boost/iostreams/detail/codecvt_helper.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -134,8 +134,7 @@
}
std::codecvt_base::result
- virtual do_unshift( State& state, Extern* first2, Extern* last2,
- Extern*& next2 ) const
+ virtual do_unshift(State&, Extern*, Extern*, Extern*&) const
{
return std::codecvt_base::ok;
}
@@ -146,7 +145,7 @@
virtual int do_encoding() const throw() { return 1; }
- virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State& state,
+ virtual int do_length( BOOST_IOSTREAMS_CODECVT_CV_QUALIFIER State&,
const Extern* first1, const Extern* last1,
std::size_t len2 ) const throw()
{
Modified: branches/release/boost/iostreams/detail/config/disable_warnings.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/config/disable_warnings.hpp (original)
+++ branches/release/boost/iostreams/detail/config/disable_warnings.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -16,6 +16,9 @@
# 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(__BORLANDC__, < 0x600)
# pragma warn -8008 // Condition always true/false.
Modified: branches/release/boost/iostreams/detail/config/rtl.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/config/rtl.hpp (original)
+++ branches/release/boost/iostreams/detail/config/rtl.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -55,12 +55,16 @@
# 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
Modified: branches/release/boost/iostreams/detail/current_directory.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/current_directory.hpp (original)
+++ branches/release/boost/iostreams/detail/current_directory.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -30,6 +30,9 @@
# 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
@@ -57,4 +60,6 @@
} } } // End namespaces detail, iostreams, boost.
+#include <boost/iostreams/detail/config/enable_warnings.hpp>
+
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_CURRENT_DIRECTORY_HPP_INCLUDED
Added: branches/release/boost/iostreams/detail/file_handle.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/iostreams/detail/file_handle.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -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
Modified: branches/release/boost/iostreams/detail/forward.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/forward.hpp (original)
+++ branches/release/boost/iostreams/detail/forward.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -12,7 +12,7 @@
# pragma once
#endif
-#include <boost/config.hpp> // BOOST_MSVC
+#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>
@@ -23,36 +23,43 @@
#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_DEFINE_FORWARDING_FUNCTIONS(mode, name, helper).
+// Macro: BOOST_IOSTREAMS_FORWARD(class, impl, device, params, args)
// Description: Defines constructors and overloads of 'open' which construct
-// a device using the given argument list and pass it to 'open_impl'.
-// Assumes that 'policy_type' is an alias for the device type.
-// Not supported on Intel 7.1 and VC6.5.
+// 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, policy, params, args) \
- class(const policy& t params()) \
+#define BOOST_IOSTREAMS_FORWARD(class, impl, device, params, args) \
+ class(const device& t params()) \
{ this->impl(::boost::iostreams::detail::wrap(t) args()); } \
- class(policy& t params()) \
+ class(device& t params()) \
{ this->impl(::boost::iostreams::detail::wrap(t) args()); } \
- class(const ::boost::reference_wrapper<policy>& ref params()) \
+ class(const ::boost::reference_wrapper<device>& ref params()) \
{ this->impl(ref args()); } \
- void open(const policy& t params()) \
+ void open(const device& t params()) \
{ this->impl(::boost::iostreams::detail::wrap(t) args()); } \
- void open(policy& t params()) \
+ void open(device& t params()) \
{ this->impl(::boost::iostreams::detail::wrap(t) args()); } \
- void open(const ::boost::reference_wrapper<policy>& ref params()) \
+ 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, policy) \
+ 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, policy) \
+ BOOST_IOSTREAMS_FORWARDING_FN, (class, impl, device) \
) \
/**/
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
@@ -61,7 +68,8 @@
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_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)) \
@@ -72,7 +80,8 @@
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_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) ); } \
@@ -84,7 +93,8 @@
#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_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)) ); } \
@@ -92,11 +102,23 @@
/**/
#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)) \
+ 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)) ); } \
BOOST_IOSTREAMS_FORWARDING_FN_I(z, n, tuple) \
/**/
+// Disable forwarding constructors if first parameter type is the same
+// as the device type
+#if !defined(BOOST_NO_SFINAE) && \
+ !BOOST_WORKAROUND(__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
Modified: branches/release/boost/iostreams/detail/is_iterator_range.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/is_iterator_range.hpp (original)
+++ branches/release/boost/iostreams/detail/is_iterator_range.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -8,8 +8,13 @@
#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 {
# if !BOOST_WORKAROUND(BOOST_MSVC, <= 1300) //---------------------------------//
@@ -39,4 +44,6 @@
} // End namespace boost.
+#include <boost/iostreams/detail/config/enable_warnings.hpp>
+
#endif // #ifndef BOOST_IOSTREAMS_DETAIL_IS_ITERATOR_RANGE_HPP_INCLUDED
Added: branches/release/boost/iostreams/detail/path.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/iostreams/detail/path.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -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/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 {
+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::filesystem::path or boost::filesystem::wpath
+ template<typename Path>
+ explicit path(const Path& p)
+ {
+ typedef typename Path::external_string_type string_type;
+ init(p, boost::type<string_type>());
+ }
+
+ // 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;
+ }
+
+ // Assignment operator taking a Boost.Filesystem path
+ template<typename Path>
+ path& operator=(const Path& p)
+ {
+ typedef typename Path::external_string_type string_type;
+ init(p, boost::type<string_type>());
+ 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&);
+
+ template<typename Path>
+ void init(const Path& p, boost::type<std::string>)
+ {
+ narrow_ = p.external_file_string();
+ wide_.clear();
+ is_wide_ = false;
+ }
+
+ template<typename Path>
+ void init(const Path& p, boost::type<std::wstring>)
+ {
+ narrow_.clear();
+ wide_ = p.external_file_string();
+ 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
Modified: branches/release/boost/iostreams/detail/restrict_impl.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/restrict_impl.hpp (original)
+++ branches/release/boost/iostreams/detail/restrict_impl.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -184,7 +184,7 @@
bad_seek();
return offset_to_position(pos_ - beg_);
}
- if (next < beg_ || end_ != -1 && next >= end_)
+ if (next < beg_ || (end_ != -1 && next >= end_))
bad_seek();
pos_ = this->component().seek(dev, next, BOOST_IOS::cur);
return offset_to_position(pos_ - beg_);
@@ -296,7 +296,7 @@
bad_seek();
return offset_to_position(pos_ - beg_);
}
- if (next < beg_ || end_ != -1 && next >= end_)
+ if (next < beg_ || (end_ != -1 && next >= end_))
bad_seek();
pos_ = iostreams::seek(this->component(), next - pos_, BOOST_IOS::cur);
return offset_to_position(pos_ - beg_);
@@ -312,7 +312,7 @@
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 )
+ (len != -1 && off + len > seq.second - seq.first) )
{
throw BOOST_IOSTREAMS_FAILURE("bad offset");
}
Modified: branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp (original)
+++ branches/release/boost/iostreams/detail/streambuf/direct_streambuf.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -220,7 +220,7 @@
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 (one || ((which & BOOST_IOS::in) != 0 && ibeg_ != 0)) {
if (!gptr()) setg(ibeg_, ibeg_, iend_);
ptrdiff_t next = 0;
switch (way) {
Modified: branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp
==============================================================================
--- branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp (original)
+++ branches/release/boost/iostreams/detail/streambuf/indirect_streambuf.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -282,8 +282,8 @@
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 )
+ if ( (output_buffered() && pptr() == 0) ||
+ (shared_buffer() && gptr() != 0) )
{
init_put_area();
}
Modified: branches/release/boost/iostreams/device/file.hpp
==============================================================================
--- branches/release/boost/iostreams/device/file.hpp (original)
+++ branches/release/boost/iostreams/device/file.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -5,14 +5,6 @@
// See http://www.boost.org/libs/iostreams for documentation.
-//
-// Contains wrappers for standard file buffers, together
-// with convenience typedefs:
-// - basic_file_source
-// - basic_file_sink
-// - basic_file
-//
-
#ifndef BOOST_IOSTREAMS_FILE_HPP_INCLUDED
#define BOOST_IOSTREAMS_FILE_HPP_INCLUDED
@@ -51,6 +43,7 @@
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 =
@@ -87,6 +80,7 @@
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;
@@ -150,6 +144,12 @@
}
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); }
Modified: branches/release/boost/iostreams/device/file_descriptor.hpp
==============================================================================
--- branches/release/boost/iostreams/device/file_descriptor.hpp (original)
+++ branches/release/boost/iostreams/device/file_descriptor.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -15,13 +15,15 @@
# pragma once
#endif
-#include <string> // file pathnames.
+#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>
@@ -30,82 +32,97 @@
namespace boost { namespace iostreams {
+// Forward declarations
+class file_descriptor_source;
+class file_descriptor_sink;
+namespace detail { struct file_descriptor_impl; }
+
class BOOST_IOSTREAMS_DECL 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;
+ 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
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
+
+ // Constructor taking a std:: string
explicit file_descriptor( 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 );
+
+ // Constructor taking a C-style string
explicit file_descriptor( const char* path,
BOOST_IOS::openmode mode =
- BOOST_IOS::in | BOOST_IOS::out,
- BOOST_IOS::openmode base_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, bool close_on_exit = false);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ void open(int fd, bool close_on_exit = false);
+#endif
+
+ // open overload taking a std::string
void open( const std::string& path,
- BOOST_IOS::openmode =
- BOOST_IOS::in | BOOST_IOS::out,
- BOOST_IOS::openmode base_mode =
+ BOOST_IOS::openmode mode =
BOOST_IOS::in | BOOST_IOS::out );
+
+ // open overload taking C-style string
void open( const char* path,
- BOOST_IOS::openmode =
- BOOST_IOS::in | BOOST_IOS::out,
- BOOST_IOS::openmode base_mode =
+ BOOST_IOS::openmode mode =
BOOST_IOS::in | BOOST_IOS::out );
- bool is_open() const { return pimpl_->flags_ != 0; }
+
+ // 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);
- void close();
- handle_type handle() const { return pimpl_->handle_; }
+ handle_type handle() const;
private:
- struct impl {
- impl() :
- #ifdef BOOST_IOSTREAMS_WINDOWS
- handle_(reinterpret_cast<handle_type>(-1)),
- #else
- handle_(-1),
- #endif
- flags_(0)
- { }
- impl(handle_type fd, bool close_on_exit)
- : handle_(fd), flags_(0)
- { if (close_on_exit) flags_ |= impl::close_on_exit; }
- ~impl()
- { if (flags_ & close_on_exit) close_impl(*this); }
- enum flags {
- close_on_exit = 1,
- append = 4
- };
- handle_type handle_;
- int flags_;
- };
- friend struct impl;
+ void init();
- static void close_impl(impl&);
-#ifdef BOOST_IOSTREAMS_WINDOWS
- static handle_type int_to_handle(int fd);
-#endif
+ // open overload taking a detail::path
+ void open( const detail::path& path,
+ BOOST_IOS::openmode,
+ BOOST_IOS::openmode = BOOST_IOS::in | BOOST_IOS::out );
- shared_ptr<impl> pimpl_;
+ typedef detail::file_descriptor_impl impl_type;
+ shared_ptr<impl_type> pimpl_;
};
-struct file_descriptor_source : private file_descriptor {
+class file_descriptor_source : private file_descriptor {
+public:
#ifdef BOOST_IOSTREAMS_WINDOWS
typedef void* handle_type; // A.k.a HANDLE
#else
@@ -117,32 +134,61 @@
device_tag,
closable_tag
{ };
- using file_descriptor::read;
- using file_descriptor::seek;
- using file_descriptor::open;
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() { }
- explicit file_descriptor_source(handle_type fd, bool close_on_exit = false)
- : file_descriptor(fd, close_on_exit)
- { }
-#ifdef BOOST_IOSTREAMS_WINDOWS
- explicit file_descriptor_source(int fd, bool close_on_exit = false)
- : file_descriptor(fd, close_on_exit)
- { }
+
+ // 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
+
+ // Constructor taking a std:: string
explicit file_descriptor_source( const std::string& path,
- BOOST_IOS::openmode m = BOOST_IOS::in )
- : file_descriptor(path, m & ~BOOST_IOS::out, BOOST_IOS::in)
- { }
+ BOOST_IOS::openmode mode = BOOST_IOS::in );
+
+ // Constructor taking a C-style string
explicit file_descriptor_source( const char* path,
- BOOST_IOS::openmode m = BOOST_IOS::in )
- : file_descriptor(path, m & ~BOOST_IOS::out, BOOST_IOS::in)
- { }
+ 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);
+
+ // 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
+
+ // 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);
};
-struct file_descriptor_sink : private file_descriptor {
+class file_descriptor_sink : private file_descriptor {
+public:
#ifdef BOOST_IOSTREAMS_WINDOWS
typedef void* handle_type; // A.k.a HANDLE
#else
@@ -154,29 +200,61 @@
device_tag,
closable_tag
{ };
- using file_descriptor::write;
- using file_descriptor::seek;
- using file_descriptor::open;
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() { }
- explicit file_descriptor_sink(handle_type fd, bool close_on_exit = false)
- : file_descriptor(fd, close_on_exit)
- { }
-#ifdef BOOST_IOSTREAMS_WINDOWS
- explicit file_descriptor_sink(int fd, bool close_on_exit = false)
- : file_descriptor(fd, close_on_exit)
- { }
+
+ // 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
+
+ // Constructor taking a std:: string
explicit file_descriptor_sink( const std::string& path,
- BOOST_IOS::openmode m = BOOST_IOS::out )
- : file_descriptor(path, m & ~BOOST_IOS::in, BOOST_IOS::out)
- { }
+ BOOST_IOS::openmode mode = BOOST_IOS::out );
+
+ // Constructor taking a C-style string
explicit file_descriptor_sink( const char* path,
- BOOST_IOS::openmode m = BOOST_IOS::out )
- : file_descriptor(path, m & ~BOOST_IOS::in, BOOST_IOS::out)
- { }
+ 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, bool close_on_exit = false);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ void open(int fd, bool close_on_exit = false);
+#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.
Modified: branches/release/boost/iostreams/device/mapped_file.hpp
==============================================================================
--- branches/release/boost/iostreams/device/mapped_file.hpp (original)
+++ branches/release/boost/iostreams/device/mapped_file.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -1,35 +1,9 @@
-// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
-// (C) Copyright 2003-2007 Jonathan Turkanis
+// (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.)
-// See http://www.boost.org/libs/iostreams for documentation.
-
-//
-// This header and its accompanying source file libs/iostreams/memmap.cpp are
-// an adaptation of Craig Henderson's memmory mapped file library. The
-// interface has been revised significantly, but the underlying OS-specific
-// code is essentially the same, with some code from Boost.Filesystem
-// mixed in. (See notations in source.)
-//
-// The following changes have been made:
-//
-// 1. OS-specific code put in a .cpp file.
-// 2. Name of main class changed to mapped_file.
-// 3. mapped_file given an interface similar to std::fstream (open(),
-// is_open(), close()) and std::string (data(), size(), begin(), end()).
-// 4. An additional class readonly_mapped_file has been provided as a
-// convenience.
-// 5. [Obsolete: Error states are reported using filesystem::error_code.]
-// 6. Read-only or read-write states are specified using ios_base::openmode.
-// 7. Access to the underlying file handles and to security parameters
-// has been removed.
-//
-
-#ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
-#define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
-
#if defined(_MSC_VER) && (_MSC_VER >= 1020)
# pragma once
#endif
@@ -44,90 +18,181 @@
#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/ios.hpp> // openmode.
+#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/type_traits/is_same.hpp>
// Must come last.
-#include <boost/iostreams/detail/config/disable_warnings.hpp>
#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_impl;
+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.
-struct mapped_file_params {
- explicit mapped_file_params()
- #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) && defined(BOOST_RWSTD_VER) || \
- defined(__BORLANDC__) && defined(_CPPLIB_VER)
- /**/
- : mode(std::ios_base::openmode(0)),
- #else
- : mode(),
- #endif
- offset(0), length(static_cast<std::size_t>(-1)),
- new_file_size(0), hint(0)
+// 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)
{ }
- explicit mapped_file_params(const std::string& path)
- : path(path),
- #if BOOST_WORKAROUND(BOOST_MSVC, < 1400) && defined(BOOST_RWSTD_VER) || \
- defined(__BORLANDC__) && defined(_CPPLIB_VER)
- mode(std::ios_base::openmode(0)),
- #else
- mode(),
- #endif
- offset(0), length(static_cast<std::size_t>(-1)),
- new_file_size(0), hint(0)
+
+ // Templated copy constructor
+ template<typename PathT>
+ basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
+ : base_type(other), path(other.path)
{ }
- std::string path;
- BOOST_IOS::openmode mode;
- stream_offset offset;
- std::size_t length;
- stream_offset new_file_size;
- const char* hint;
+
+ 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 {
+class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base {
private:
- struct safe_bool_helper { int x; }; // From Bronek Kozicki.
- typedef int safe_bool_helper::* safe_bool;
- friend struct operations<mapped_file_source>;
+ 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;
+ 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;
+ typedef std::size_t size_type;
+ typedef const char* iterator;
BOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1));
- mapped_file_source() { }
- explicit mapped_file_source(mapped_file_params);
- explicit mapped_file_source( const std::string& path,
+ // 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------------------------------------------//
- void open(mapped_file_params params);
- void open( const std::string& path,
+ 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;
- BOOST_IOS::openmode mode() const;
+ mapmode flags() const;
//--------------Container interface---------------------------------------//
@@ -141,109 +206,308 @@
// Returns the allocation granularity for virtual memory. Values passed
// as offsets must be multiples of this value.
static int alignment();
+
private:
- friend class mapped_file;
- typedef detail::mapped_file_impl impl_type;
- void open_impl(mapped_file_params);
+ 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 {
+class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base {
private:
- typedef mapped_file_source delegate_type;
- delegate_type delegate_;
- friend struct operations<mapped_file>;
+ 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;
+ 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;
+ 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() { }
- explicit mapped_file(mapped_file_params p);
- explicit mapped_file( const std::string& path,
+
+ // 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 );
- //--------------Conversion to readonly_mapped_file------------------------//
+ // 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------------------------------------------//
- void open(mapped_file_params p);
- void open( const std::string& path,
+ // 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 delegate_type::safe_bool() const { return delegate_; }
- bool operator!() const { return !is_open(); }
- BOOST_IOS::openmode mode() const { return delegate_.mode(); }
+ 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
- {
- return (mode() & BOOST_IOS::out) ?
- const_cast<char*>(delegate_.data()) :
- 0;
- }
+ char* data() const;
const char* const_data() const { return delegate_.data(); }
iterator begin() const { return data(); }
- const_iterator const_begin() const { return data(); }
+ const_iterator const_begin() const { return const_data(); }
iterator end() const { return data() + size(); }
- const_iterator const_end() const { return data() + size(); }
+ 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_;
};
-struct BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file {
- friend struct operations<mapped_file_sink>;
- typedef char char_type;
+//------------------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;
- explicit mapped_file_sink(mapped_file_params p);
- explicit mapped_file_sink( const std::string& path,
+ 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 );
- void open(mapped_file_params p);
- void open( const std::string& path,
+ 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 );
+ 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)
+ throw new BOOST_IOSTREAMS_FAILURE("invalid flags");
+ } else {
+ if (params.mode & BOOST_IOS::out)
+ throw new 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; }
+
+//------------------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)
+ throw new BOOST_IOSTREAMS_FAILURE("invalid flags");
+ } else {
+ if (params.mode & BOOST_IOS::in)
+ throw new 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<boost::iostreams::mapped_file_source>
- : detail::close_impl<closable_tag>
+struct operations<mapped_file_source>
+ : boost::iostreams::detail::close_impl<closable_tag>
{
static std::pair<char*, char*>
- input_sequence(boost::iostreams::mapped_file_source& src)
+ input_sequence(mapped_file_source& src)
{
return std::make_pair( const_cast<char*>(src.begin()),
const_cast<char*>(src.end()) );
@@ -251,35 +515,79 @@
};
template<>
-struct operations<boost::iostreams::mapped_file_sink>
- : detail::close_impl<closable_tag>
+struct operations<mapped_file>
+ : boost::iostreams::detail::close_impl<closable_tag>
{
static std::pair<char*, char*>
- output_sequence(boost::iostreams::mapped_file_sink& sink)
+ input_sequence(mapped_file& file)
{
- return std::make_pair(sink.begin(), sink.end());
+ return std::make_pair(file.begin(), file.end());
}
-};
-
-template<>
-struct operations<boost::iostreams::mapped_file>
- : detail::close_impl<closable_tag>
-{
static std::pair<char*, char*>
- input_sequence(boost::iostreams::mapped_file& file)
+ 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(boost::iostreams::mapped_file& file)
+ output_sequence(mapped_file_sink& sink)
{
- return std::make_pair(file.begin(), file.end());
+ 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
-#include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC.
-
-#endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
Added: branches/release/boost/iostreams/filter/grep.hpp
==============================================================================
--- (empty file)
+++ branches/release/boost/iostreams/filter/grep.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -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) && (_MSC_VER >= 1020)
+# 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
Modified: branches/release/boost/iostreams/filter/gzip.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/gzip.hpp (original)
+++ branches/release/boost/iostreams/filter/gzip.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -19,6 +19,7 @@
#include <boost/config.hpp> // STATIC_CONSTANT, STDC_NAMESPACE,
// DINKUMWARE_STDLIB, __STL_CONFIG_H.
#include <algorithm> // min.
+#include <cassert>
#include <cstdio> // EOF.
#include <cstddef> // size_t.
#include <ctime> // std::time_t.
@@ -34,7 +35,8 @@
#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/pipeline.hpp>
+#include <boost/iostreams/putback.hpp>
// Must come last.
#if defined(BOOST_MSVC)
@@ -47,6 +49,8 @@
#endif
namespace boost { namespace iostreams {
+
+//------------------Definitions of constants----------------------------------//
namespace gzip {
@@ -59,6 +63,7 @@
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 {
@@ -118,6 +123,8 @@
} // End namespace gzip.
+//------------------Definition of gzip_params---------------------------------//
+
//
// Class name: gzip_params.
// Description: Subclass of zlib_params with an additional field
@@ -142,6 +149,8 @@
std::time_t mtime;
};
+//------------------Definition of gzip_error----------------------------------//
+
//
// Class name: gzip_error.
// Description: Subclass of std::ios_base::failure thrown to indicate
@@ -163,6 +172,8 @@
int zlib_error_code_;
};
+//------------------Definition of gzip_compressor-----------------------------//
+
//
// Template name: gzip_compressor
// Description: Model of OutputFilter implementing compression in the
@@ -283,7 +294,7 @@
flags_ = 0;
}
- enum flag_type {
+ enum state_type {
f_header_done = 1,
f_body_done = f_header_done << 1,
f_footer_done = f_body_done << 1
@@ -297,6 +308,81 @@
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
@@ -304,6 +390,9 @@
//
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
@@ -316,35 +405,72 @@
template<typename Source>
std::streamsize read(Source& src, char_type* s, std::streamsize n)
{
- if ((flags_ & f_header_read) == 0) {
- non_blocking_adapter<Source> nb(src);
- read_header(nb);
- flags_ |= f_header_read;
- }
-
- if ((flags_ & f_footer_read) != 0)
- return -1;
-
- try {
- std::streamsize result = 0;
- std::streamsize amt;
- if ((amt = base_type::read(src, s, n)) != -1) {
- result += amt;
- if (amt < n) { // Double check for EOF.
- amt = base_type::read(src, s + result, n - result);
- if (amt != -1)
+ 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)) {
+ throw 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) {
+ throw gzip_error(e);
+ }
+ } else { // state_ == s_footer
+ int c = boost::iostreams::get(peek);
+ if (traits_type::is_eof(c)) {
+ throw gzip_error(gzip::bad_footer);
+ } else if (traits_type::would_block(c)) {
+ break;
+ }
+ footer_.process(c);
+ if (footer_.done()) {
+ if (footer_.crc() != this->crc())
+ throw gzip_error(gzip::bad_crc);
+ int 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 (amt == -1) {
- non_blocking_adapter<Source> nb(src);
- read_footer(nb);
- flags_ |= f_footer_read;
- }
- return result;
- } catch (const zlib_error& e) {
- throw gzip_error(e);
}
+ if (peek.has_unconsumed_input()) {
+ putback_ = peek.unconsumed_input();
+ } else {
+ putback_.clear();
+ }
+ return result != 0 || state_ != s_done ?
+ result :
+ -1;
}
template<typename Source>
@@ -353,136 +479,95 @@
try {
base_type::close(src, BOOST_IOS::in);
} catch (const zlib_error& e) {
- flags_ = 0;
+ state_ = s_start;
+ header_.reset();
+ footer_.reset();
throw gzip_error(e);
}
- flags_ = 0;
+ state_ = s_start;
}
- 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_; }
+ 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:
- typedef basic_zlib_decompressor<Alloc> base_type;
- typedef BOOST_IOSTREAMS_CHAR_TRAITS(char) traits_type;
- static bool is_eof(int c) { return traits_type::eq_int_type(c, EOF); }
static gzip_params make_params(int window_bits);
+ // Source adapter allowing an arbitrary character sequence to be put back.
template<typename Source>
- static uint8_t read_uint8(Source& src, int error)
- {
- int c;
- if ((c = boost::iostreams::get(src)) == EOF || c == WOULD_BLOCK)
- throw gzip_error(error);
- return static_cast<uint8_t>(traits_type::to_char_type(c));
- }
+ 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;
- template<typename Source>
- static uint32_t read_uint32(Source& src, int error)
- {
- uint8_t b1 = read_uint8(src, error);
- uint8_t b2 = read_uint8(src, error);
- uint8_t b3 = read_uint8(src, error);
- uint8_t b4 = read_uint8(src, error);
- return b1 + (b2 << 8) + (b3 << 16) + (b4 << 24);
- }
+ // 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;
+ }
- template<typename Source>
- std::string read_string(Source& src)
- {
- std::string result;
- while (true) {
- int c;
- if (is_eof(c = boost::iostreams::get(src)))
- throw gzip_error(gzip::bad_header);
- else if (c == 0)
- return result;
- else
- result += static_cast<char>(c);
+ // 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;
+ return true;
+ } else {
+ return boost::iostreams::putback(src_, c);
+ }
+ }
+ void putback(const string_type& s)
+ {
+ putback_.replace(0, offset_, s);
+ offset_ = 0;
}
- }
-
- template<typename Source>
- void read_header(Source& src) // Source is non-blocking.
- {
- // Reset saved values.
- #if BOOST_WORKAROUND(__GNUC__, == 2) && defined(__STL_CONFIG_H) || \
- BOOST_WORKAROUND(BOOST_DINKUMWARE_STDLIB, == 1) \
- /**/
- file_name_.erase(0, std::string::npos);
- comment_.erase(0, std::string::npos);
- #else
- file_name_.clear();
- comment_.clear();
- #endif
- os_ = gzip::os_unknown;
- mtime_ = 0;
-
- int flags;
- // Read header, without checking header crc.
- if ( boost::iostreams::get(src) != gzip::magic::id1 || // ID1.
- boost::iostreams::get(src) != gzip::magic::id2 || // ID2.
- is_eof(boost::iostreams::get(src)) || // CM.
- is_eof(flags = boost::iostreams::get(src)) ) // FLG.
+ // Returns true if some characters have been putback but not re-read.
+ bool has_unconsumed_input() const
{
- throw gzip_error(gzip::bad_header);
+ return offset_ < static_cast<std::streamsize>(putback_.size());
}
- mtime_ = read_uint32(src, gzip::bad_header); // MTIME.
- read_uint8(src, gzip::bad_header); // XFL.
- os_ = read_uint8(src, gzip::bad_header); // OS.
- if (flags & boost::iostreams::gzip::flags::text)
- flags_ |= f_text;
-
- // Skip extra field. (From J. Halleaux; see note at top.)
- if (flags & gzip::flags::extra) {
- int length =
- static_cast<int>(
- read_uint8(src, gzip::bad_header) +
- (read_uint8(src, gzip::bad_header) << 8)
- );
- // length is garbage if EOF but the loop below will quit anyway.
- do { }
- while (length-- != 0 && !is_eof(boost::iostreams::get(src)));
- }
-
- if (flags & gzip::flags::name) // Read file name.
- file_name_ = read_string(src);
- if (flags & gzip::flags::comment) // Read comment.
- comment_ = read_string(src);
- if (flags & gzip::flags::header_crc) { // Skip header crc.
- read_uint8(src, gzip::bad_header);
- read_uint8(src, gzip::bad_header);
+
+ // 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_;
+ };
- template<typename Source>
- void read_footer(Source& src)
- {
- typename base_type::string_type footer =
- this->unconsumed_input();
- int c;
- while (!is_eof(c = boost::iostreams::get(src)))
- footer += c;
- detail::range_adapter<input, std::string>
- rng(footer.begin(), footer.end());
- if (read_uint32(rng, gzip::bad_footer) != this->crc())
- throw gzip_error(gzip::bad_crc);
- if (static_cast<int>(read_uint32(rng, gzip::bad_footer)) != this->total_out())
- throw gzip_error(gzip::bad_length);
- }
- enum flag_type {
- f_header_read = 1,
- f_footer_read = f_header_read << 1,
- f_text = f_footer_read << 1
+ 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
};
- std::string file_name_;
- std::string comment_;
- int os_;
- std::time_t mtime_;
- int flags_;
+ detail::gzip_header header_;
+ detail::gzip_footer footer_;
+ string_type putback_;
+ int state_;
};
BOOST_IOSTREAMS_PIPABLE(basic_gzip_decompressor, 1)
@@ -580,7 +665,7 @@
basic_gzip_decompressor<Alloc>::basic_gzip_decompressor
(int window_bits, int buffer_size)
: base_type(make_params(window_bits), buffer_size),
- os_(gzip::os_unknown), mtime_(0), flags_(0)
+ state_(s_start)
{ }
template<typename Alloc>
Modified: branches/release/boost/iostreams/filter/line.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/line.hpp (original)
+++ branches/release/boost/iostreams/filter/line.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -18,6 +18,7 @@
#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>
@@ -61,7 +62,10 @@
closable_tag
{ };
protected:
- basic_line_filter() : pos_(string_type::npos), state_(0) { }
+ basic_line_filter(bool suppress_newlines = false)
+ : pos_(string_type::npos),
+ flags_(suppress_newlines ? f_suppress : 0)
+ { }
public:
virtual ~basic_line_filter() { }
@@ -69,8 +73,8 @@
std::streamsize read(Source& src, char_type* s, std::streamsize n)
{
using namespace std;
- assert(!(state_ & f_write));
- state_ |= f_read;
+ assert(!(flags_ & f_write));
+ flags_ |= f_read;
// Handle unfinished business.
std::streamsize result = 0;
@@ -80,7 +84,7 @@
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 test, and
+ // 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;
@@ -94,8 +98,8 @@
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
{
using namespace std;
- assert(!(state_ & f_read));
- state_ |= f_write;
+ assert(!(flags_ & f_read));
+ flags_ |= f_write;
// Handle unfinished business.
if (pos_ != string_type::npos && !write_line(snk))
@@ -122,10 +126,10 @@
template<typename Sink>
void close(Sink& snk, BOOST_IOS::openmode which)
{
- if ((state_ & f_read) && which == BOOST_IOS::in)
+ if ((flags_ & f_read) && which == BOOST_IOS::in)
close_impl();
- if ((state_ & f_write) && which == BOOST_IOS::out) {
+ if ((flags_ & f_write) && which == BOOST_IOS::out) {
try {
if (!cur_line_.empty())
write_line(snk);
@@ -168,7 +172,7 @@
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())
+ if (c == traits_type::newline() && (flags_ & f_suppress) == 0)
cur_line_ += c;
}
return c; // status indicator.
@@ -179,9 +183,11 @@
template<typename Sink>
bool write_line(Sink& snk)
{
- string_type line = do_filter(cur_line_) + traits_type::newline();
+ 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(snk, line.data(), amt) == amt;
+ bool result = iostreams::write_if(snk, line.data(), amt) == amt;
if (result)
clear();
return result;
@@ -190,7 +196,7 @@
void close_impl()
{
clear();
- state_ = 0;
+ flags_ &= f_suppress;
}
void clear()
@@ -200,13 +206,14 @@
}
enum flag_type {
- f_read = 1,
- f_write = f_read << 1
+ f_read = 1,
+ f_write = f_read << 1,
+ f_suppress = f_write << 1
};
string_type cur_line_;
typename string_type::size_type pos_;
- int state_;
+ int flags_;
};
BOOST_IOSTREAMS_PIPABLE(basic_line_filter, 2)
Modified: branches/release/boost/iostreams/filter/newline.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/newline.hpp (original)
+++ branches/release/boost/iostreams/filter/newline.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -211,7 +211,7 @@
}
template<typename Sink>
- void close(Sink& dest, BOOST_IOS::openmode which)
+ void close(Sink& dest, BOOST_IOS::openmode)
{
typedef typename iostreams::category_of<Sink>::type category;
if ((flags_ & f_write) != 0 && (flags_ & f_has_CR) != 0)
@@ -398,7 +398,7 @@
}
template<typename Sink>
- void close(Sink&, BOOST_IOS::openmode which)
+ void close(Sink&, BOOST_IOS::openmode)
{
using iostreams::newline::final_newline;
Modified: branches/release/boost/iostreams/filter/symmetric.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/symmetric.hpp (original)
+++ branches/release/boost/iostreams/filter/symmetric.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -71,8 +71,9 @@
> >
class symmetric_filter {
public:
- typedef typename char_type_of<SymmetricFilter>::type char_type;
- typedef std::basic_string<char_type> string_type;
+ typedef typename char_type_of<SymmetricFilter>::type char_type;
+ typedef BOOST_IOSTREAMS_CHAR_TRAITS(char_type) traits_type;
+ typedef std::basic_string<char_type, traits_type, Alloc> string_type;
struct category
: dual_use,
filter_tag,
@@ -123,7 +124,7 @@
// If no more characters are available without blocking, or
// if read request has been satisfied, return.
- if ( status == f_would_block && buf.ptr() == buf.eptr() ||
+ if ( (status == f_would_block && buf.ptr() == buf.eptr()) ||
next_s == end_s )
{
return static_cast<std::streamsize>(next_s - s);
@@ -152,7 +153,7 @@
}
template<typename Sink>
- void close(Sink& snk, BOOST_IOS::openmode which)
+ void close(Sink& snk, BOOST_IOS::openmode)
{
if ((state() & f_write) != 0) {
@@ -217,7 +218,6 @@
template<typename Sink>
bool flush(Sink& snk, mpl::true_)
{
- typedef char_traits<char_type> traits_type;
std::streamsize amt =
static_cast<std::streamsize>(buf().ptr() - buf().data());
std::streamsize result =
Modified: branches/release/boost/iostreams/filter/zlib.hpp
==============================================================================
--- branches/release/boost/iostreams/filter/zlib.hpp (original)
+++ branches/release/boost/iostreams/filter/zlib.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -47,8 +47,9 @@
typedef unsigned char byte;
typedef unsigned long ulong;
-typedef void* (*alloc_func)(void*, zlib::uint, zlib::uint);
-typedef void (*free_func)(void*, void*);
+// Prefix 'x' prevents symbols from being redefined when Z_PREFIX is defined
+typedef void* (*xalloc_func)(void*, zlib::uint, zlib::uint);
+typedef void (*xfree_func)(void*, void*);
// Compression levels
@@ -191,8 +192,8 @@
char*& dest_begin, char* dest_end );
void after( const char*& src_begin, char*& dest_begin,
bool compress );
- int deflate(int flush);
- int inflate(int flush);
+ int xdeflate(int flush); // Prefix 'x' prevents symbols from being
+ int xinflate(int flush); // redefined when Z_PREFIX is defined
void reset(bool compress, bool realloc);
public:
zlib::ulong crc() const { return crc_; }
@@ -201,8 +202,8 @@
private:
void do_init( const zlib_params& p, bool compress,
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- zlib::alloc_func,
- zlib::free_func,
+ zlib::xalloc_func,
+ zlib::xfree_func,
#endif
void* derived );
void* stream_; // Actual type: z_stream*.
@@ -341,7 +342,7 @@
char*& dest_begin, char* dest_end, bool flush )
{
before(src_begin, src_end, dest_begin, dest_end);
- int result = deflate(flush ? zlib::finish : zlib::no_flush);
+ int result = xdeflate(flush ? zlib::finish : zlib::no_flush);
after(src_begin, dest_begin, true);
zlib_error::check(result);
return result != zlib::stream_end;
@@ -374,7 +375,7 @@
char*& dest_begin, char* dest_end, bool /* flush */ )
{
before(src_begin, src_end, dest_begin, dest_end);
- int result = inflate(zlib::sync_flush);
+ int result = xinflate(zlib::sync_flush);
after(src_begin, dest_begin, false);
zlib_error::check(result);
return result != zlib::stream_end;
Modified: branches/release/boost/iostreams/invert.hpp
==============================================================================
--- branches/release/boost/iostreams/invert.hpp (original)
+++ branches/release/boost/iostreams/invert.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -44,6 +44,7 @@
template<typename Filter>
class inverse {
private:
+ BOOST_STATIC_ASSERT(is_filter<Filter>::value);
typedef typename category_of<Filter>::type base_category;
typedef reference_wrapper<Filter> filter_ref;
public:
Modified: branches/release/boost/iostreams/skip.hpp
==============================================================================
--- branches/release/boost/iostreams/skip.hpp (original)
+++ branches/release/boost/iostreams/skip.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -100,8 +100,8 @@
> can_seek;
BOOST_STATIC_ASSERT(
( can_seek::value ||
- is_convertible<filter_mode, input>::value &&
- is_convertible<device_mode, input>::value )
+ (is_convertible<filter_mode, input>::value &&
+ is_convertible<device_mode, input>::value) )
);
detail::skip(flt, dev, off, which, can_seek());
}
Modified: branches/release/boost/iostreams/stream.hpp
==============================================================================
--- branches/release/boost/iostreams/stream.hpp (original)
+++ branches/release/boost/iostreams/stream.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -123,7 +123,6 @@
detail::stream_traits<
Device, Tr
>::stream_type stream_type;
- typedef Device policy_type;
public:
stream() { }
BOOST_IOSTREAMS_FORWARD( stream, open_impl, Device,
Modified: branches/release/boost/iostreams/stream_buffer.hpp
==============================================================================
--- branches/release/boost/iostreams/stream_buffer.hpp (original)
+++ branches/release/boost/iostreams/stream_buffer.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -73,7 +73,6 @@
detail::stream_buffer_traits<
T, Tr, Alloc, Mode
>::type base_type;
- typedef T policy_type;
public:
typedef typename char_type_of<T>::type char_type;
struct category
Modified: branches/release/boost/iostreams/tee.hpp
==============================================================================
--- branches/release/boost/iostreams/tee.hpp (original)
+++ branches/release/boost/iostreams/tee.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -40,13 +40,15 @@
typedef typename detail::param_type<Device>::type param_type;
typedef typename char_type_of<Device>::type char_type;
struct category
- : multichar_output_filter_tag,
+ : dual_use_filter_tag,
+ multichar_tag,
closable_tag,
flushable_tag,
localizable_tag,
optimally_buffered_tag
{ };
+ BOOST_STATIC_ASSERT(is_device<Device>::value);
BOOST_STATIC_ASSERT((
is_convertible< // Using mode_of causes failures on VC6-7.0.
BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
@@ -57,6 +59,18 @@
: detail::filter_adapter<Device>(dev)
{ }
+ 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) {
+ std::streamsize result2 = iostreams::write(this->component(), s, result);
+ (void) result2; // Suppress 'unused variable' warning.
+ assert(result == result2);
+ }
+ return result;
+ }
+
template<typename Sink>
std::streamsize write(Sink& snk, const char_type* s, std::streamsize n)
{
@@ -68,7 +82,7 @@
}
template<typename Next>
- void close(Next&)
+ void close(Next&, BOOST_IOS::openmode)
{
detail::close_all(this->component());
}
@@ -86,48 +100,77 @@
//
// Template name: tee_device.
// Template paramters:
-// Sink1 - A blocking Sink.
-// Sink2 - A blocking Sink.
+// Device - A blocking Device.
+// Sink - A blocking Sink.
//
-template<typename Sink1, typename Sink2>
+template<typename Device, typename Sink>
class tee_device {
public:
- typedef typename detail::param_type<Sink1>::type param_type1;
- typedef typename detail::param_type<Sink2>::type param_type2;
- typedef typename detail::value_type<Sink1>::type value_type1;
- typedef typename detail::value_type<Sink2>::type value_type2;
- typedef typename char_type_of<Sink1>::type char_type;
+ typedef typename detail::param_type<Device>::type device_param;
+ typedef typename detail::param_type<Sink>::type sink_param;
+ typedef typename detail::value_type<Device>::type device_value;
+ typedef typename detail::value_type<Sink>::type sink_value;
+ typedef typename char_type_of<Device>::type char_type;
+ typedef typename
+ mpl::if_<
+ is_convertible<
+ BOOST_DEDUCED_TYPENAME
+ iostreams::category_of<Device>::type,
+ output
+ >,
+ output,
+ input
+ >::type mode;
+ BOOST_STATIC_ASSERT(is_device<Device>::value);
+ BOOST_STATIC_ASSERT(is_device<Sink>::value);
BOOST_STATIC_ASSERT((
is_same<
char_type,
- BOOST_DEDUCED_TYPENAME char_type_of<Sink2>::type
- >::value
- ));
- BOOST_STATIC_ASSERT((
- is_convertible< // Using mode_of causes failures on VC6-7.0.
- BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink1>::type, output
+ BOOST_DEDUCED_TYPENAME char_type_of<Sink>::type
>::value
));
BOOST_STATIC_ASSERT((
- is_convertible< // Using mode_of causes failures on VC6-7.0.
- BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink2>::type, output
+ is_convertible<
+ BOOST_DEDUCED_TYPENAME iostreams::category_of<Sink>::type,
+ output
>::value
));
struct category
- : output,
+ : mode,
device_tag,
closable_tag,
flushable_tag,
localizable_tag,
optimally_buffered_tag
{ };
- tee_device(param_type1 sink1, param_type2 sink2)
- : sink1_(sink1), sink2_(sink2)
+ tee_device(device_param device, sink_param sink)
+ : dev_(device), sink_(sink)
{ }
+ std::streamsize read(char_type* s, std::streamsize n)
+ {
+ BOOST_STATIC_ASSERT((
+ is_convertible<
+ BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, input
+ >::value
+ ));
+ std::streamsize result1 = iostreams::read(dev_, s, n);
+ if (result1 != -1) {
+ std::streamsize result2 = iostreams::write(sink_, s, result1);
+ (void) result1; // Suppress 'unused variable' warning.
+ (void) result2;
+ assert(result1 == result2);
+ }
+ return result1;
+ }
std::streamsize write(const char_type* s, std::streamsize n)
{
- std::streamsize result1 = iostreams::write(sink1_, s, n);
- std::streamsize result2 = iostreams::write(sink2_, s, n);
+ BOOST_STATIC_ASSERT((
+ is_convertible<
+ BOOST_DEDUCED_TYPENAME iostreams::category_of<Device>::type, output
+ >::value
+ ));
+ std::streamsize result1 = iostreams::write(dev_, s, n);
+ std::streamsize result2 = iostreams::write(sink_, s, n);
(void) result1; // Suppress 'unused variable' warning.
(void) result2;
assert(result1 == n && result2 == n);
@@ -135,38 +178,38 @@
}
void close()
{
- detail::execute_all( detail::call_close_all(sink1_),
- detail::call_close_all(sink2_) );
+ detail::execute_all( detail::call_close_all(dev_),
+ detail::call_close_all(sink_) );
}
bool flush()
{
- bool r1 = iostreams::flush(sink1_);
- bool r2 = iostreams::flush(sink2_);
+ bool r1 = iostreams::flush(dev_);
+ bool r2 = iostreams::flush(sink_);
return r1 && r2;
}
template<typename Locale>
void imbue(const Locale& loc)
{
- iostreams::imbue(sink1_, loc);
- iostreams::imbue(sink2_, loc);
+ iostreams::imbue(dev_, loc);
+ iostreams::imbue(sink_, loc);
}
std::streamsize optimal_buffer_size() const
{
- return (std::max) ( iostreams::optimal_buffer_size(sink1_),
- iostreams::optimal_buffer_size(sink2_) );
+ return (std::max) ( iostreams::optimal_buffer_size(dev_),
+ iostreams::optimal_buffer_size(sink_) );
}
private:
- value_type1 sink1_;
- value_type2 sink2_;
+ device_value dev_;
+ sink_value sink_;
};
template<typename Sink>
tee_filter<Sink> tee(const Sink& snk)
{ return tee_filter<Sink>(snk); }
-template<typename Sink1, typename Sink2>
-tee_device<Sink1, Sink2> tee(const Sink1& sink1, const Sink2& sink2)
-{ return tee_device<Sink1, Sink2>(sink1, sink2); }
+template<typename Device, typename Sink>
+tee_device<Device, Sink> tee(const Device& dev, const Sink& sink)
+{ return tee_device<Device, Sink>(dev, sink); }
} } // End namespaces iostreams, boost.
Modified: branches/release/boost/iostreams/traits.hpp
==============================================================================
--- branches/release/boost/iostreams/traits.hpp (original)
+++ branches/release/boost/iostreams/traits.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -21,6 +21,7 @@
#include <iosfwd> // stream types, char_traits.
#include <boost/config.hpp> // partial spec, deduced typename.
+#include <boost/detail/workaround.hpp>
#include <boost/iostreams/categories.hpp>
#include <boost/iostreams/detail/bool_trait_def.hpp>
#include <boost/iostreams/detail/config/wide_streams.hpp>
@@ -38,7 +39,11 @@
# include <boost/range/iterator_range.hpp>
# include <boost/range/value_type.hpp>
#endif // #if BOOST_WORKAROUND(BOOST_MSVC, <= 1300)
-#include <boost/type_traits/is_convertible.hpp>
+#include <boost/ref.hpp>
+#include <boost/type_traits/is_convertible.hpp>
+
+// Must come last.
+#include <boost/iostreams/detail/config/disable_warnings.hpp>
namespace boost { namespace iostreams {
@@ -269,6 +274,16 @@
>::type type;
};
+// Partial specialization for reference wrappers
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
+
+template<typename T>
+struct category_of< reference_wrapper<T> >
+ : category_of<T>
+ { };
+
+#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
+
//------------------Definition of get_category--------------------------------//
//
@@ -292,7 +307,7 @@
#endif
};
-//------------------Definition of mode----------------------------------------//
+//------------------Definition of mode_of-------------------------------------//
namespace detail {
@@ -323,6 +338,16 @@
template<typename T> // Borland 5.6.4 requires this circumlocution.
struct mode_of : detail::io_mode_impl< detail::io_mode_id<T>::value > { };
+
+// Partial specialization for reference wrappers
+#ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //---------------------------//
+
+template<typename T>
+struct mode_of< reference_wrapper<T> >
+ : mode_of<T>
+ { };
+
+#endif // #ifndef BOOST_NO_TEMPLATE_PARTIAL_SPECIALIZATION //-----------------//
//------------------Definition of is_device, is_filter and is_direct----------//
@@ -361,4 +386,6 @@
} } // End namespaces iostreams, boost.
+#include <boost/iostreams/detail/config/enable_warnings.hpp>
+
#endif // #ifndef BOOST_IOSTREAMS_IO_TRAITS_HPP_INCLUDED
Modified: branches/release/libs/iostreams/build/Jamfile.v2
==============================================================================
--- branches/release/libs/iostreams/build/Jamfile.v2 (original)
+++ branches/release/libs/iostreams/build/Jamfile.v2 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -138,7 +138,7 @@
if $(z)
{
- sources += boost_zlib zlib.cpp ;
+ sources += boost_zlib zlib.cpp gzip.cpp ;
}
local bz2 = [ create-library bzip2 : libbz2 bz2 :
Modified: branches/release/libs/iostreams/doc/bibliography.html
==============================================================================
--- branches/release/libs/iostreams/doc/bibliography.html (original)
+++ branches/release/libs/iostreams/doc/bibliography.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -69,6 +69,10 @@
<TD>Henderson, C. <I>Boost Memory Mapped File</I>.<A CLASS="footnote_ref" NAME="note_1_ref" HREF="#note_1"><SUP>[1]</SUP></A> Available in the Boost Sandbox.</TD>
</TR>
<TR>
+ <TH ALIGN="left" VALIGN="top"><A NAME="iso">[I<SPAN STYLE="font-size:80%">EEE</SPAN>]</A></TD><TD WIDTH="1em"></TH>
+ <TD><I>I<SPAN STYLE="font-size:80%">EEE</SPAN> Std 1003.1, 2004 Edition</I>, Shells & Utilities volume. <I>See</I> http://www.opengroup.org/onlinepubs/009695399/utilities/grep.html
.</TD></TD>
+</TR>
+<TR>
<TH ALIGN="left" VALIGN="top"><A NAME="iso">[I<SPAN STYLE="font-size:80%">SO</SPAN>]</A></TD><TD WIDTH="1em"></TH>
<TD><I>I<SPAN STYLE="font-size:80%">SO</SPAN>/I<SPAN STYLE="font-size:80%">EC</SPAN> 14882:1998(E) Programming Language C++, 2nd ed.</I>. I<SPAN STYLE="font-size:80%">SO</SPAN>/I<SPAN STYLE="font-size:80%">EC</SPAN>, 2003.
</TR>
Modified: branches/release/libs/iostreams/doc/classes/bzip2.html
==============================================================================
--- branches/release/libs/iostreams/doc/classes/bzip2.html (original)
+++ branches/release/libs/iostreams/doc/classes/bzip2.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -292,6 +292,7 @@
int main()
{
<SPAN CLASS="keyword">using</SPAN> <SPAN CLASS="keyword">namespace</SPAN> std;
+ <SPAN CLASS="keyword">using</SPAN> <SPAN CLASS="keyword">namespace</SPAN> boost::iostreams;
ifstream file(<SPAN CLASS="literal">"hello.bz2"</SPAN>, ios_base::in | ios_base::binary);
filtering_streambuf<input> in;
Added: branches/release/libs/iostreams/doc/classes/grep_filter.html
==============================================================================
--- (empty file)
+++ branches/release/libs/iostreams/doc/classes/grep_filter.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,155 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<HTML>
+<HEAD>
+ <TITLE>Class Template basic_grep_filter</TITLE>
+ <LINK REL="stylesheet" HREF="../../../../boost.css">
+ <LINK REL="stylesheet" HREF="../theme/iostreams.css">
+</HEAD>
+<BODY>
+
+<!-- Begin Banner -->
+
+ <H1 CLASS="title">Class Template <CODE>basic_grep_filter</CODE></H1>
+ <HR CLASS="banner">
+
+<!-- End Banner -->
+
+<DL class="page-index">
+ <DT>Description</DT>
+ <DT>Headers</DT>
+ <DT>Installation</DT>
+ <DT>Reference</DT>
+</DL>
+
+<HR>
+
+<A NAME="description"></A>
+<H2>Description</H2>
+
+<P>
+ The class template <CODE>basic_grep_filter</CODE> filters a character sequence line by line using a regular expression provided at construction, in a manner similar to the command-line utility <i>grep</i> (<A CLASS="bib_ref" HREF="../bibliography.html#grep">[IEEE]</A>). The filter uses regular expressions from the Boost Regular Expression Library (<A CLASS="bib_ref" HREF="../bibliography.html#maddock">[Maddock]</A>).
+</P>
+<P>
+ By default, the filtered character sequence consists of those lines of the unfilitered sequence that contain a subsequence matching the regular expression. By specifying appropriate options at construction, <CODE>basic_grep_filter</CODE> can be made to pass through only those lines which exactly match the regular expression (as if the option <i>-x</i> had been passed to the command-line utility) or only those lines that <i>do not</i> contain a match (as if the option <i>-v</i> had been passed to the command-line utility).
+</P>
+<P>
+ A running count of the lines in the filtered character sequence is available via the member function <code>count</code>.
+</P>
+
+<A NAME="headers"></A>
+<H2>Headers</H2>
+
+<DL class="page-index">
+ <DT><A CLASS="header" HREF="../../../../boost/iostreams/filter/grep.hpp"><CODE><boost/iostreams/filter/grep.hpp></CODE></A></DT>
+</DL>
+
+<A NAME="installation"></A>
+<H2>Installation</H2>
+
+<P>
+ The template <CODE>basic_grep_filter</CODE> uses the Boost Regular Expression Library, which must be built separately. See here for details.
+</P>
+
+<A NAME="reference"></A>
+<H2>Reference</H2>
+
+<H4>Synopsis</H4>
+
+<PRE CLASS="broken_ie"><SPAN CLASS="keyword">namespace</SPAN> boost { <SPAN CLASS="keyword">namespace</SPAN> iostreams {
+
+<SPAN CLASS="preprocessor">#include</SPAN> <A CLASS="header" HREF="../../../../boost/function.hpp" TARGET="_top"><SPAN CLASS="literal"><boost/function.hpp></SPAN></A>
+<SPAN CLASS="preprocessor">#include</SPAN> <A CLASS="header" HREF="../../../../boost/regex.hpp" TARGET="_top"><SPAN CLASS="literal"><boost/regex.hpp></SPAN></A>
+
+<SPAN CLASS="keyword">namespace</SPAN> grep {
+
+<SPAN CLASS="keyword">const</SPAN> <SPAN CLASS="keyword">int</SPAN> invert;
+<SPAN CLASS="keyword">const</SPAN> <SPAN CLASS="keyword">int</SPAN> whole_line;
+
+}
+
+<SPAN CLASS="keyword">template</SPAN>< <SPAN CLASS="keyword">typename</SPAN> Ch,
+ <SPAN CLASS="keyword">typename</SPAN> Tr = regex_traits<Ch>,
+ <SPAN CLASS="keyword">typename</SPAN> Alloc = std::allocator<Ch> >
+<SPAN CLASS="keyword">class</SPAN> basic_grep_filter {
+<SPAN CLASS="keyword">public:</SPAN>
+ <A CLASS="documented" HREF="#constructor">basic_grep_filter</A>( <SPAN CLASS="keyword">const</SPAN> basic_regex<Ch, Tr, Alloc>& pattern,
+ regex_constants::match_flag_type flags =
+ regex_constants::match_default,
+ <SPAN CLASS="keyword">int</SPAN> options = <SPAN CLASS="numeric_literal">0</SPAN> );
+ <SPAN CLASS="keyword">int</SPAN> <A CLASS="documented" HREF="#count">count</A>() <SPAN CLASS="keyword">const</SPAN>;
+};
+
+<SPAN CLASS="keyword">typedef</SPAN> basic_grep_filter<<SPAN CLASS="keyword">char</SPAN>> <SPAN CLASS="defined">grep_filter</SPAN>;
+<SPAN CLASS="keyword">typedef</SPAN> basic_grep_filter<<SPAN CLASS="keyword">wchar_t</SPAN>> <SPAN CLASS="defined">wgrep_filter</SPAN>;
+
+} } // End namespace boost::io</PRE>
+
+<A NAME="template_params"></A>
+<H4>Template parameters</H4>
+
+<TABLE STYLE="margin-left:2em" BORDER=0 CELLPADDING=2>
+<TR>
+ <TR>
+ <TD VALIGN="top"><I>Ch</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>The character type</TD>
+ </TR>
+ <TR>
+ <TD VALIGN="top"><I>Tr</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>The regular expression traits type</TD>
+ </TR>
+ <TR>
+ <TD VALIGN="top"><I>Alloc</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>A standard library allocator type (<A CLASS="bib_ref" HREF="../bibliography.html#iso">[ISO]</A>, 20.1.5), used to allocate character buffers</TD>
+ </TR>
+</TABLE>
+
+<A NAME="constructor"></A>
+<H4><CODE>basic_grep_filter::basic_grep_filter</CODE></H4>
+
+<PRE CLASS="broken_ie"> <B>basic_grep_filter</B>( <SPAN CLASS="keyword">const</SPAN> basic_regex<Ch, Tr, Alloc>& pattern,
+ regex_constants::match_flag_type flags =
+ regex_constants::match_default,
+ <SPAN CLASS="keyword">int</SPAN> options = <SPAN CLASS="numeric_literal">0</SPAN> );</PRE>
+
+<P>Constructs a <CODE>basic_grep_filter</CODE> from the given regular expression, match flags, and grep options. The parameters have the following interpretations:</P>
+
+<TABLE STYLE="margin-left:2em" BORDER=0 CELLPADDING=2>
+<TR>
+ <TR>
+ <TD VALIGN="top"><I>pattern</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>The regular expression to be matched against the stream of unfiltered data</TD>
+ </TR>
+ <TR>
+ <TD VALIGN="top"><I>flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>The flags passed to regex_search or regex_match to specify regular expression matching behavior</TD>
+ </TR>
+ <TR>
+ <TD VALIGN="top"><I>options</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
+ <TD>A bitwise OR of zero or more constants from the namespace <CODE>boost::iostreams::grep</CODE>. Currently two constants are recongnized: <CODE>grep::whole_line</CODE> causes the filter to pass through only those lines which exactly match the regular expression, and <CODE>grep::invert</CODE> causes the filter to pass through only those lines that <i>do not</i> contain a match.</TD>
+ </TR>
+</TABLE>
+
+</P>
+
+<A NAME="count"></A>
+<H4><CODE>basic_grep_filter::count</CODE></H4>
+
+<A NAME="second_constructor"></A>
+
+<PRE CLASS="broken_ie"> <SPAN CLASS="keyword">int</SPAN> count() <SPAN CLASS="keyword">const</SPAN>;</PRE>
+
+<P>Returns a running count of the lines passed through from the unfiltered character sequence to the filtered character sequence. The count is reset to zero automatically when the filter begins processing a new character sequence.</P>
+
+<!-- Begin Footer -->
+
+<HR>
+<P CLASS="copyright">Revised 28 May 2008</P>
+
+<P CLASS="copyright">© Copyright 2008 CodeRage, LLC</P>
+<P CLASS="copyright">
+ 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)
+</P>
+
+<!-- End Footer -->
+
+</BODY>
Modified: branches/release/libs/iostreams/doc/classes/regex_filter.html
==============================================================================
--- branches/release/libs/iostreams/doc/classes/regex_filter.html (original)
+++ branches/release/libs/iostreams/doc/classes/regex_filter.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -30,10 +30,10 @@
The class template <CODE>basic_regex_filter</CODE> performs text substitutions using regular expressions from the Boost Regular Expression Library (<A CLASS="bib_ref" HREF="../bibliography.html#maddock">[Maddock]</A>).
</P>
<P>
- Each <CODE>basic_regex_filter</CODE> stores a regular expression and a formatting function. As unfiltered data is scanned for matches, portions of data which fall between regular expression matches are forwarded unchanged. Each time a match is found, the corresponding match_results
object is passed to the formatting function and the return value is forwarded in place of the matched text.
+ Each <CODE>basic_regex_filter</CODE> stores a regular expression and a formatting function. As unfiltered data is scanned for matches, portions of data which fall between regular expression matches are forwarded unchanged. Each time a match is found, the corresponding match_results
object is passed to the formatting function and the return value is forwarded in place of the matched text.
</P>
<P>
- Users may construct instances of <CODE>basic_regex_filter</CODE> either from formatting functions or from format strings.
+ Users may construct instances of <CODE>basic_regex_filter</CODE> either from formatting functions or from format strings.
</P>
<P>
Since a regular expression may need to look arbitrarily far ahead in a character sequence, <CODE>basic_regex_filter</CODE> derives from aggregate_filter
and processes an entire sequence of data at once.
@@ -50,7 +50,7 @@
<H2>Installation</H2>
<P>
- The template <CODE>basic_regex_filter</CODE> uses the Boost Regular Expression Library, which must be built separately. See here for details.
+ The template <CODE>basic_regex_filter</CODE> uses the Boost Regular Expression Library, which must be built separately. See here for details.
</P>
<A NAME="reference"></A>
@@ -109,7 +109,7 @@
</TR>
<TR>
<TD VALIGN="top"><I>Tr</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>The regular expression traits type</TD>
+ <TD>The regular expression traits type</TD>
</TR>
<TR>
<TD VALIGN="top"><I>Alloc</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
@@ -164,7 +164,7 @@
</TR>
<TR>
<TD VALIGN="top"><I>flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>Used to construct a regex_iterator</TD>
+ <TD>Used to construct a regex_iterator</TD>
</TR>
</TABLE>
@@ -189,15 +189,15 @@
</TR>
<TR>
<TD VALIGN="top"><I>fmt</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>A format string which specifies the replacement text for each regular expression match, using match_results::format</TD>
+ <TD>A format string which specifies the replacement text for each regular expression match, using match_results::format</TD>
</TR>
<TR>
<TD VALIGN="top"><I>flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>Used to construct a regex_iterator</TD>
+ <TD>Used to construct a regex_iterator</TD>
</TR>
<TR>
<TD VALIGN="top"><I>fmt_flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>The flags argument to match_results::format</TD>
+ <TD>The flags argument to match_results::format</TD>
</TR>
</TABLE>
@@ -220,15 +220,15 @@
</TR>
<TR>
<TD VALIGN="top"><I>fmt</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>A format string which specifies the replacement text for each regular expression match, using match_results::format</TD>
+ <TD>A format string which specifies the replacement text for each regular expression match, using match_results::format</TD>
</TR>
<TR>
<TD VALIGN="top"><I>flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>Used to construct a regex_iterator</TD>
+ <TD>Used to construct a regex_iterator</TD>
</TR>
<TR>
<TD VALIGN="top"><I>fmt_flags</I></TD><TD WIDTH="2em" VALIGN="top">-</TD>
- <TD>The flags argument to match_results::format</TD>
+ <TD>The flags argument to match_results::format</TD>
</TR>
</TABLE>
Modified: branches/release/libs/iostreams/doc/menu.html
==============================================================================
--- branches/release/libs/iostreams/doc/menu.html (original)
+++ branches/release/libs/iostreams/doc/menu.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -121,6 +121,7 @@
.add("<CODE>basic_file</CODE>", "classes/file.html#file").parent()
.add("<CODE>basic_file_sink</CODE>", "classes/file.html#file_sink").parent()
.add("<CODE>basic_file_source</CODE>", "classes/file.html#file_source").parent()
+ .add("<CODE>basic_grep_filter</CODE>", "classes/grep_filter.html").parent()
.add("<CODE>basic_gzip_compressor</CODE>", "classes/gzip.html#basic_gzip_compressor").parent()
.add("<CODE>basic_gzip_decompressor</CODE>", "classes/gzip.html#basic_gzip_decompressor").parent()
.add("<CODE>basic_line_filter</CODE>", "classes/line_filter.html").parent()
@@ -159,6 +160,8 @@
.add("<CODE>filtering_streambuf</CODE>", "classes/filtering_streambuf.html").parent()
.add("<CODE>filter</CODE>", "classes/filter.html").parent().parent()
.add("G", "classes/classes.html#g")
+ .add("<CODE>grep_filter</CODE>", "classes/grep_filter.html").parent()
+ .add("<CODE>gzip_compressor</CODE>", "classes/gzip.html#basic_gzip_compressor").parent()
.add("<CODE>gzip_compressor</CODE>", "classes/gzip.html#basic_gzip_compressor").parent()
.add("<CODE>gzip_decompressor</CODE>", "classes/gzip.html#basic_gzip_decompressor").parent()
.add("<CODE>gzip_error</CODE>", "classes/gzip.html#gzip_error").parent()
@@ -215,6 +218,7 @@
.add("<CODE>wfile_sink</CODE>", "classes/file.html#file_sink").parent()
.add("<CODE>wfile_source</CODE>", "classes/file.html#file_source").parent()
.add("<CODE>wfilter</CODE>", "classes/filter.html").parent()
+ .add("<CODE>wgrep_filter</CODE>", "classes/grep_filter.html").parent()
.add("<CODE>wline_filter</CODE>", "classes/line_filter.html#reference").parent()
.add("<CODE>wnull_sink</CODE>", "classes/null.html#null_sink").parent()
.add("<CODE>wnull_source</CODE>", "classes/null.html#null_source").parent()
Modified: branches/release/libs/iostreams/doc/quick_reference.html
==============================================================================
--- branches/release/libs/iostreams/doc/quick_reference.html (original)
+++ branches/release/libs/iostreams/doc/quick_reference.html 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -218,7 +218,7 @@
<!-- -------------- Text -------------- -->
<TR>
- <TH ROWSPAN=4>Text</TH>
+ <TH ROWSPAN=5>Text</TH>
<TD>
<A HREF="classes/counter.html"><CODE>basic_counter</CODE></A>
</TD>
@@ -238,6 +238,15 @@
</TR>
<TR>
<TD>
+ basic_grep_filter
+ </TD>
+ <TD>grep.hpp
</TD>
+ <TD>
+ Filters character sequences line by line using regular expressions from the Boost Regular Expression Library.
+ </TD>
+</TR>
+<TR>
+ <TD>
<A HREF="classes/newline_filter.html#newline_checker"><CODE>newline_checker</CODE></A>
</TD>
<TD ROWSPAN=2>newline.hpp
</TD>
Modified: branches/release/libs/iostreams/example/container_device.hpp
==============================================================================
--- branches/release/libs/iostreams/example/container_device.hpp (original)
+++ branches/release/libs/iostreams/example/container_device.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -5,8 +5,8 @@
// See http://www.boost.org/libs/iostreams for documentation.
-#ifndef BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED
-#define BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED
+#ifndef BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
+#define BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
#include <algorithm> // copy, min.
#include <cassert>
@@ -152,4 +152,4 @@
} } } // End namespaces example, iostreams, boost.
-#endif // #ifndef BOOST_IOSTREAMS_CONTAINTER_DEVICE_HPP_INCLUDED
+#endif // #ifndef BOOST_IOSTREAMS_EXAMPLE_CONTAINTER_DEVICE_HPP_INCLUDED
Modified: branches/release/libs/iostreams/src/file_descriptor.cpp
==============================================================================
--- branches/release/libs/iostreams/src/file_descriptor.cpp (original)
+++ branches/release/libs/iostreams/src/file_descriptor.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -5,9 +5,6 @@
// 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.
-
// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
// knows that we are building the library (possibly exporting code), rather
// than using it (possibly importing code).
@@ -21,6 +18,7 @@
#include <boost/iostreams/detail/config/dyn_link.hpp>
#include <boost/iostreams/detail/config/rtl.hpp> // BOOST_IOSTREAMS_FD_XXX
#include <boost/iostreams/detail/config/windows_posix.hpp>
+#include <boost/iostreams/detail/system_failure.hpp>
#include <boost/iostreams/detail/ios.hpp> // openmodes, failure.
#include <boost/iostreams/device/file_descriptor.hpp>
#include <boost/integer_traits.hpp>
@@ -43,68 +41,102 @@
namespace boost { namespace iostreams {
-//------------------Implementation of file_descriptor-------------------------//
+//------------------Definition of file_descriptor_impl------------------------//
-file_descriptor::file_descriptor() : pimpl_(new impl) { }
-
-file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
- : pimpl_(new impl(fd, close_on_exit))
- { }
+namespace detail {
+// Contains the platform dependant implementation
+struct file_descriptor_impl {
+ file_descriptor_impl();
+ ~file_descriptor_impl();
+ void open(file_handle fd, bool close_on_exit);
#ifdef BOOST_IOSTREAMS_WINDOWS
- file_descriptor::file_descriptor(int fd, bool close_on_exit)
- : pimpl_(new impl(int_to_handle(fd), close_on_exit))
- { }
+ void open(int fd, bool close_on_exit);
#endif
+ void open(const detail::path&, BOOST_IOS::openmode);
+ bool is_open() const;
+ void close();
+ std::streamsize read(char* s, std::streamsize n);
+ std::streamsize write(const char* s, std::streamsize n);
+ std::streampos seek(stream_offset off, BOOST_IOS::seekdir way);
+ static file_handle invalid_handle();
+ enum flags {
+ close_on_exit = 1,
+ append = 4
+ };
+ file_handle handle_;
+ int flags_;
+};
-file_descriptor::file_descriptor( const char* path,
- BOOST_IOS::openmode mode,
- BOOST_IOS::openmode base_mode )
- : pimpl_(new impl)
-{ open(std::string(path), mode, base_mode); }
+//------------------Implementation of file_descriptor_impl--------------------//
-file_descriptor::file_descriptor( const std::string& path,
- BOOST_IOS::openmode mode,
- BOOST_IOS::openmode base_mode )
- : pimpl_(new impl)
-{ open(path, mode, base_mode); }
-
-void file_descriptor::open
- ( const std::string& path, BOOST_IOS::openmode m,
- BOOST_IOS::openmode base )
+file_descriptor_impl::file_descriptor_impl()
+ : handle_(invalid_handle()), flags_(0)
+ { }
+
+file_descriptor_impl::~file_descriptor_impl()
+{
+ if (flags_ & close_on_exit) {
+ try {
+ close();
+ } catch (...) { }
+ }
+}
+
+void file_descriptor_impl::open(file_handle fd, bool close_on_exit)
+{
+ handle_ = fd;
+ flags_ = close_on_exit ?
+ file_descriptor_impl::close_on_exit :
+ 0;
+}
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+void file_descriptor_impl::open(int fd, bool close_on_exit)
+{ open(reinterpret_cast<file_handle>(_get_osfhandle(fd)), close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+void file_descriptor_impl::open(const detail::path& p, BOOST_IOS::openmode mode)
{
- using namespace std;
- m |= base;
#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
DWORD dwDesiredAccess;
DWORD dwCreationDisposition;
- if ( (m & (BOOST_IOS::in | BOOST_IOS::out))
+ if ( (mode & (BOOST_IOS::in | BOOST_IOS::out))
==
(BOOST_IOS::in | BOOST_IOS::out) )
{
- if (m & BOOST_IOS::app)
+ if (mode & BOOST_IOS::app)
throw BOOST_IOSTREAMS_FAILURE("bad open mode");
dwDesiredAccess = GENERIC_READ | GENERIC_WRITE;
dwCreationDisposition =
- (m & BOOST_IOS::trunc) ?
+ (mode & BOOST_IOS::trunc) ?
OPEN_ALWAYS :
OPEN_EXISTING;
- } else if (m & BOOST_IOS::in) {
- if (m & (BOOST_IOS::app |BOOST_IOS::trunc))
+ } else if (mode & BOOST_IOS::in) {
+ if (mode & (BOOST_IOS::app |BOOST_IOS::trunc))
throw BOOST_IOSTREAMS_FAILURE("bad open mode");
dwDesiredAccess = GENERIC_READ;
dwCreationDisposition = OPEN_EXISTING;
- } else if (m & BOOST_IOS::out) {
+ } else if (mode & BOOST_IOS::out) {
dwDesiredAccess = GENERIC_WRITE;
dwCreationDisposition = OPEN_ALWAYS;
- if (m & BOOST_IOS::app)
- pimpl_->flags_ |= impl::append;
+ if (mode & BOOST_IOS::app)
+ flags_ |= append;
} else {
throw BOOST_IOSTREAMS_FAILURE("bad open mode");
}
- HANDLE handle =
- ::CreateFileA( path.c_str(),
+ HANDLE handle = p.is_wide() ?
+ ::CreateFileW( p.c_wstr(),
+ dwDesiredAccess,
+ FILE_SHARE_READ | FILE_SHARE_WRITE,
+ NULL, // lpSecurityAttributes
+ dwCreationDisposition,
+ FILE_ATTRIBUTE_NORMAL,
+ NULL ) : // hTemplateFile
+ ::CreateFileA( p.c_str(),
dwDesiredAccess,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL, // lpSecurityAttributes
@@ -112,33 +144,33 @@
FILE_ATTRIBUTE_NORMAL,
NULL ); // hTemplateFile
if (handle != INVALID_HANDLE_VALUE) {
- pimpl_->handle_ = handle;
- pimpl_->flags_ |= impl::close_on_exit;
+ handle_ = handle;
+ flags_ |= close_on_exit;
} else {
- pimpl_->flags_ = 0;
- throw BOOST_IOSTREAMS_FAILURE("bad open");
+ flags_ = 0;
+ throw_system_failure("failed opening file");
}
#else // #ifdef BOOST_IOSTREAMS_WINDOWS //------------------------------------//
// Calculate oflag argument to open.
int oflag = 0;
- if ( (m & (BOOST_IOS::in | BOOST_IOS::out))
+ if ( (mode & (BOOST_IOS::in | BOOST_IOS::out))
==
(BOOST_IOS::in | BOOST_IOS::out) )
{
- assert(!(m & BOOST_IOS::app));
+ assert(!(mode & BOOST_IOS::app));
oflag |= O_RDWR;
- } else if (m & BOOST_IOS::in) {
- assert(!(m & (BOOST_IOS::app |BOOST_IOS::trunc)));
+ } else if (mode & BOOST_IOS::in) {
+ assert(!(mode & (BOOST_IOS::app |BOOST_IOS::trunc)));
oflag |= O_RDONLY;
- } else if (m & BOOST_IOS::out) {
+ } else if (mode & BOOST_IOS::out) {
oflag |= O_WRONLY;
- m |= BOOST_IOS::trunc;
- if (m & BOOST_IOS::app)
+ mode |= BOOST_IOS::trunc;
+ if (mode & BOOST_IOS::app)
oflag |= O_APPEND;
}
- if (m & BOOST_IOS::trunc)
+ if (mode & BOOST_IOS::trunc)
oflag |= O_CREAT;
#ifdef _LARGEFILE64_SOURCE
oflag |= O_LARGEFILE;
@@ -152,70 +184,83 @@
// Open file.
- int fd = BOOST_IOSTREAMS_FD_OPEN(path.c_str(), oflag, pmode);
+ int fd = BOOST_IOSTREAMS_FD_OPEN(p.c_str(), oflag, pmode);
if (fd == -1) {
- throw BOOST_IOSTREAMS_FAILURE("bad open");
+ throw system_failure("failed opening file");
} else {
- pimpl_->handle_ = fd;
- pimpl_->flags_ = impl::close_on_exit;
+ handle_ = fd;
+ flags_ = close_on_exit;
}
#endif // #ifndef BOOST_IOSTREAMS_WINDOWS //----------------------------------//
}
-void file_descriptor::open
- ( const char* path, BOOST_IOS::openmode m,
- BOOST_IOS::openmode base )
-{ open(std::string(path), m, base); }
+bool file_descriptor_impl::is_open() const
+{ return handle_ != invalid_handle(); }
-std::streamsize file_descriptor::read(char_type* s, std::streamsize n)
+void file_descriptor_impl::close()
+{
+ if (handle_ != invalid_handle()) {
+ bool success =
+ #ifdef BOOST_IOSTREAMS_WINDOWS
+ ::CloseHandle(handle_) == 1;
+ #else
+ BOOST_IOSTREAMS_FD_CLOSE(handle_) != -1;
+ #endif
+ if (!success)
+ throw_system_failure("failed closing file");
+ handle_ = invalid_handle();
+ flags_ = 0;
+ }
+}
+
+std::streamsize file_descriptor_impl::read(char* s, std::streamsize n)
{
#ifdef BOOST_IOSTREAMS_WINDOWS
DWORD result;
- if (!::ReadFile(pimpl_->handle_, s, n, &result, NULL))
- throw detail::bad_read();
+ if (!::ReadFile(handle_, s, n, &result, NULL))
+ throw_system_failure("failed reading");
return result == 0 ? -1 : static_cast<std::streamsize>(result);
#else // #ifdef BOOST_IOSTREAMS_WINDOWS
errno = 0;
- std::streamsize result = BOOST_IOSTREAMS_FD_READ(pimpl_->handle_, s, n);
+ std::streamsize result = BOOST_IOSTREAMS_FD_READ(handle_, s, n);
if (errno != 0)
- throw detail::bad_read();
+ throw_system_failure("failed reading");
return result == 0 ? -1 : result;
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
}
-std::streamsize file_descriptor::write(const char_type* s, std::streamsize n)
+std::streamsize file_descriptor_impl::write(const char* s, std::streamsize n)
{
#ifdef BOOST_IOSTREAMS_WINDOWS
- if (pimpl_->flags_ & impl::append) {
+ if (flags_ & append) {
DWORD const dwResult =
- ::SetFilePointer(pimpl_->handle_, 0, NULL, FILE_END);
+ ::SetFilePointer(handle_, 0, NULL, FILE_END);
if ( dwResult == INVALID_SET_FILE_POINTER &&
::GetLastError() != NO_ERROR )
{
- throw detail::bad_seek();
+ throw_system_failure("failed seeking within file");
}
}
DWORD ignore;
- if (!::WriteFile(pimpl_->handle_, s, n, &ignore, NULL))
- throw detail::bad_write();
+ if (!::WriteFile(handle_, s, n, &ignore, NULL))
+ throw_system_failure("failed writing");
return n;
#else // #ifdef BOOST_IOSTREAMS_WINDOWS
- int amt = BOOST_IOSTREAMS_FD_WRITE(pimpl_->handle_, s, n);
- if (amt < n)
- throw detail::bad_write(); // Handles blocking fd's only.
+ int amt = BOOST_IOSTREAMS_FD_WRITE(handle_, s, n);
+ if (amt < n) // Handles blocking fd's only.
+ throw_system_failure("failed writing");
return n;
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
}
-std::streampos file_descriptor::seek
+std::streampos file_descriptor_impl::seek
(stream_offset off, BOOST_IOS::seekdir way)
{
- using namespace std;
#ifdef BOOST_IOSTREAMS_WINDOWS
LONG lDistanceToMove = static_cast<LONG>(off & 0xffffffff);
LONG lDistanceToMoveHigh = static_cast<LONG>(off >> 32);
DWORD dwResultLow =
- ::SetFilePointer( pimpl_->handle_,
+ ::SetFilePointer( handle_,
lDistanceToMove,
&lDistanceToMoveHigh,
way == BOOST_IOS::beg ?
@@ -226,7 +271,7 @@
if ( dwResultLow == INVALID_SET_FILE_POINTER &&
::GetLastError() != NO_ERROR )
{
- throw detail::bad_seek();
+ throw system_failure("failed seeking");
} else {
return offset_to_position(
(stream_offset(lDistanceToMoveHigh) << 32) + dwResultLow
@@ -240,7 +285,7 @@
}
stream_offset result =
BOOST_IOSTREAMS_FD_SEEK(
- pimpl_->handle_,
+ handle_,
static_cast<BOOST_IOSTREAMS_FD_OFFSET>(off),
( way == BOOST_IOS::beg ?
SEEK_SET :
@@ -249,38 +294,196 @@
SEEK_END )
);
if (result == -1)
- throw detail::bad_seek();
+ throw system_failure("failed seeking");
return offset_to_position(result);
#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
}
-void file_descriptor::close() { close_impl(*pimpl_); }
-
-void file_descriptor::close_impl(impl& i)
+// Returns the value stored in a file_handle variable when no file is open
+file_handle file_descriptor_impl::invalid_handle()
{
#ifdef BOOST_IOSTREAMS_WINDOWS
- if (i.handle_ != reinterpret_cast<handle_type>(-1)) {
- if (!::CloseHandle(i.handle_))
- throw BOOST_IOSTREAMS_FAILURE("bad close");
- i.handle_ = reinterpret_cast<handle_type>(-1);
- i.flags_ = 0;
- return;
- }
-#else // #ifdef BOOST_IOSTREAMS_WINDOWS
- if (i.handle_ != -1) {
- if (BOOST_IOSTREAMS_FD_CLOSE(i.handle_) == -1)
- throw BOOST_IOSTREAMS_FAILURE("bad close");
- i.handle_ = -1;
- i.flags_ = 0;
- }
-#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+ return INVALID_HANDLE_VALUE;
+#else
+ return -1;
+#endif
}
-#ifdef BOOST_IOSTREAMS_WINDOWS
-file_descriptor::handle_type file_descriptor::int_to_handle(int fd)
+} // End namespace detail.
+
+//------------------Implementation of file_descriptor-------------------------//
+
+file_descriptor::file_descriptor() : pimpl_(new impl_type) { }
+
+file_descriptor::file_descriptor(handle_type fd, bool close_on_exit)
+ : pimpl_(new impl_type)
+{ open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+file_descriptor::file_descriptor(int fd, bool close_on_exit)
+ : pimpl_(new impl_type)
+{ open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+file_descriptor::file_descriptor( const std::string& path,
+ BOOST_IOS::openmode mode )
+ : pimpl_(new impl_type)
+{ open(path, mode); }
+
+file_descriptor::file_descriptor( const char* path,
+ BOOST_IOS::openmode mode )
+ : pimpl_(new impl_type)
+{ open(path, mode); }
+
+file_descriptor::file_descriptor(const file_descriptor& other)
+ : pimpl_(other.pimpl_)
+ { }
+
+void file_descriptor::open(handle_type fd, bool close_on_exit)
+{ pimpl_->open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+void file_descriptor::open(int fd, bool close_on_exit)
+{ pimpl_->open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+void file_descriptor::open(const std::string& path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+void file_descriptor::open(const char* path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+bool file_descriptor::is_open() const { return pimpl_->is_open(); }
+
+void file_descriptor::close() { pimpl_->close(); }
+
+std::streamsize file_descriptor::read(char_type* s, std::streamsize n)
+{ return pimpl_->read(s, n); }
+
+std::streamsize file_descriptor::write(const char_type* s, std::streamsize n)
+{ return pimpl_->write(s, n); }
+
+std::streampos file_descriptor::seek(stream_offset off, BOOST_IOS::seekdir way)
+{ return pimpl_->seek(off, way); }
+
+detail::file_handle file_descriptor::handle() const { return pimpl_->handle_; }
+
+void file_descriptor::init() { pimpl_.reset(new impl_type); }
+
+void file_descriptor::open(
+ const detail::path& path,
+ BOOST_IOS::openmode mode,
+ BOOST_IOS::openmode base )
{
- return reinterpret_cast<handle_type>(_get_osfhandle(fd));
+ mode |= base;
+ pimpl_->open(path, mode);
+}
+
+//------------------Implementation of file_descriptor_source------------------//
+
+file_descriptor_source::file_descriptor_source(
+ handle_type fd, bool close_on_exit)
+{ open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+file_descriptor_source::file_descriptor_source(int fd, bool close_on_exit)
+{ open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+file_descriptor_source::file_descriptor_source(
+ const std::string& path, BOOST_IOS::openmode mode)
+{ open(path, mode); }
+
+file_descriptor_source::file_descriptor_source(
+ const char* path, BOOST_IOS::openmode mode)
+{ open(path, mode); }
+
+file_descriptor_source::file_descriptor_source(
+ const file_descriptor_source& other)
+ : file_descriptor(static_cast<const file_descriptor&>(other))
+ { }
+
+void file_descriptor_source::open(handle_type fd, bool close_on_exit)
+{ file_descriptor::open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+void file_descriptor_source::open(int fd, bool close_on_exit)
+{ file_descriptor::open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+void file_descriptor_source::open(
+ const std::string& path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+void file_descriptor_source::open(
+ const char* path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+void file_descriptor_source::open(
+ const detail::path& path, BOOST_IOS::openmode mode)
+{
+ if (mode & (BOOST_IOS::out | BOOST_IOS::app | BOOST_IOS::trunc))
+ throw BOOST_IOSTREAMS_FAILURE("invalid mode");
+ file_descriptor::open(path, mode, BOOST_IOS::in);
+}
+
+//------------------Implementation of file_descriptor_sink--------------------//
+
+file_descriptor_sink::file_descriptor_sink(
+ handle_type fd, bool close_on_exit)
+{ open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+file_descriptor_sink::file_descriptor_sink(int fd, bool close_on_exit)
+{ open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+file_descriptor_sink::file_descriptor_sink(
+ const std::string& path, BOOST_IOS::openmode mode)
+{ open(path, mode); }
+
+file_descriptor_sink::file_descriptor_sink(
+ const char* path, BOOST_IOS::openmode mode)
+{ open(path, mode); }
+
+file_descriptor_sink::file_descriptor_sink(const file_descriptor_sink& other)
+ : file_descriptor(static_cast<const file_descriptor&>(other))
+ { }
+
+void file_descriptor_sink::open(handle_type fd, bool close_on_exit)
+{ file_descriptor::open(fd, close_on_exit); }
+
+#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+
+void file_descriptor_sink::open(int fd, bool close_on_exit)
+{ file_descriptor::open(fd, close_on_exit); }
+
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+
+void file_descriptor_sink::open(
+ const std::string& path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+void file_descriptor_sink::open(
+ const char* path, BOOST_IOS::openmode mode)
+{ open(detail::path(path), mode); }
+
+void file_descriptor_sink::open(
+ const detail::path& path, BOOST_IOS::openmode mode)
+{
+ if (mode & BOOST_IOS::in)
+ throw BOOST_IOSTREAMS_FAILURE("invalid mode");
+ file_descriptor::open(path, mode, BOOST_IOS::out);
}
-#endif
} } // End namespaces iostreams, boost.
Added: branches/release/libs/iostreams/src/file_times.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/iostreams/src/file_times.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,158 @@
+/*
+ * 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: libs/iostreams/src/file_times.cpp
+ * Date: Sun Jun 22 14:23:12 MDT 2008
+ * Copyright: Jorge Lodos and 2008 CodeRage, LLC
+ * Author: Jorge Lodos and Jonathan Turkanis
+ * Contact: turkanis at coderage dot com
+ *
+ * Implements the functions declared in the header
+ * <boost/iostreams/detail/file_times.hpp>.
+ */
+
+// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
+// knows that we are building the library (possibly exporting code), rather
+// than using it (possibly importing code).
+#define BOOST_IOSTREAMS_SOURCE
+
+#include <ctime>
+#include <boost/iostreams/detail/config/windows_posix.hpp>
+#include <boost/iostreams/detail/file_times.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 <fcntl.h>
+# include <sys/stat.h>
+# include <sys/time.h> // futimes
+# include <sys/types.h> // struct stat.
+#endif
+
+// Must come last
+#include <boost/iostreams/detail/config/disable_warnings.hpp>
+
+namespace boost { namespace iostreams { namespace detail {
+
+std::time_t last_read_time(file_handle h)
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ FILETIME ft_access;
+ if (!::GetFileTime(h, NULL, &ft_access, NULL))
+ throw_system_failure("failed querying last access time");
+ SYSTEMTIME st_access;
+ if (!FileTimeToSystemTime(&ft_access, &st_access))
+ throw_system_failure("failed querying last access time");
+ std::tm tm;
+ tm.tm_sec = st_access.wSecond;
+ tm.tm_min = st_access.wMinute;
+ tm.tm_hour = st_access.wHour;
+ tm.tm_mday = st_access.wDay;
+ tm.tm_mon = st_access.wMonth - 1;
+ tm.tm_year = st_access.wYear - 1900;
+ return std::mktime(&tm);
+#else
+ struct stat info;
+ if (::fstat(h, &info) == -1)
+ throw_system_failure("failed querying last access time");
+ return info.st_atime;
+#endif
+}
+
+void set_last_read_time(file_handle h, time_t tm)
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ struct std::tm* t = std::gmtime(&tm);
+ if (t == NULL)
+ throw_system_failure("failed settting last access time");
+ SYSTEMTIME st_access;
+ st_access.wSecond = t->tm_sec;
+ st_access.wMinute = t->tm_min;
+ st_access.wHour = t->tm_hour;
+ st_access.wDay = t->tm_mday;
+ st_access.wMonth = t->tm_mon + 1;
+ st_access.wYear = t->tm_year + 1900;
+ FILETIME ft_access;
+ if (!SystemTimeToFileTime(&st_access, &ft_access))
+ throw_system_failure("failed settting last access time");
+ if (!::SetFileTime(h, NULL, &ft_access, NULL))
+ throw_system_failure("failed settting last access time");
+#else
+ struct stat info;
+ if (::fstat(h, &info) == -1)
+ throw_system_failure("failed settting last access time");
+ struct timeval tv[2];
+ tv[0].tv_sec = tm;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = info.st_mtime;
+ tv[1].tv_usec = 0;
+ if (futimes(h, tv) != 0)
+ throw_system_failure("failed settting last access time");
+#endif
+}
+
+std::time_t last_write_time(file_handle h)
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ FILETIME ft_modification;
+ if (!::GetFileTime(h, NULL, NULL, &ft_modification))
+ throw_system_failure("failed querying last modification time");
+ SYSTEMTIME st_modification;
+ if (!FileTimeToSystemTime(&ft_modification, &st_modification))
+ throw_system_failure("failed querying last modification time");
+ std::tm tm;
+ tm.tm_sec = st_modification.wSecond;
+ tm.tm_min = st_modification.wMinute;
+ tm.tm_hour = st_modification.wHour;
+ tm.tm_mday = st_modification.wDay;
+ tm.tm_mon = st_modification.wMonth - 1;
+ tm.tm_year = st_modification.wYear - 1900;
+ return std::mktime(&tm);
+#else
+ struct stat info;
+ if (::fstat(h, &info) == -1)
+ throw_system_failure("failed querying last modification time");
+ return info.st_mtime;
+#endif
+}
+
+void set_last_write_time(file_handle h, time_t tm)
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ struct std::tm* t = std::gmtime(&tm);
+ if (t == NULL)
+ throw_system_failure("failed settting last modification time");
+ SYSTEMTIME st_modification;
+ st_modification.wSecond = t->tm_sec;
+ st_modification.wMinute = t->tm_min;
+ st_modification.wHour = t->tm_hour;
+ st_modification.wDay = t->tm_mday;
+ st_modification.wMonth = t->tm_mon + 1;
+ st_modification.wYear = t->tm_year + 1900;
+ FILETIME ft_modification;
+ if (!SystemTimeToFileTime(&st_modification, &ft_modification))
+ throw_system_failure("failed settting last modification time");
+ if(!::SetFileTime(h, NULL, &ft_modification, NULL))
+ throw_system_failure("failed settting last modification time");
+#else
+ struct stat info;
+ if (::fstat(h, &info) == -1)
+ throw_system_failure("failed settting last modification time");
+ struct timeval tv[2];
+ tv[0].tv_sec = info.st_atime;
+ tv[0].tv_usec = 0;
+ tv[1].tv_sec = tm;
+ tv[1].tv_usec = 0;
+ if (futimes(h, tv) != 0)
+ throw_system_failure("failed settting last modification time");
+#endif
+}
+
+} } } // End namespaces detail, iostreams, boost.
+
+#include <boost/iostreams/detail/config/enable_warnings.hpp>
Added: branches/release/libs/iostreams/src/gzip.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/iostreams/src/gzip.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,173 @@
+// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
+// (C) Copyright 2003-2007 Jonathan Turkanis
+// Distributed under the Boost Software License, Version 1.0. (See accompanying
+// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
+
+// See http://www.boost.org/libs/iostreams for documentation.
+
+// To configure Boost to work with libbz2, see the
+// installation instructions here:
+// http://boost.org/libs/iostreams/doc/index.html?path=7
+
+// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
+// knows that we are building the library (possibly exporting code), rather
+// than using it (possibly importing code).
+#define BOOST_IOSTREAMS_SOURCE
+
+#include <boost/iostreams/detail/config/dyn_link.hpp>
+#include <boost/iostreams/filter/gzip.hpp>
+
+namespace boost { namespace iostreams {
+
+//------------------Implementation of gzip_header-----------------------------//
+
+namespace detail {
+
+void gzip_header::process(char c)
+{
+ uint8_t value = static_cast<uint8_t>(c);
+ switch (state_) {
+ case s_id1:
+ if (value != gzip::magic::id1)
+ throw gzip_error(gzip::bad_header);
+ state_ = s_id2;
+ break;
+ case s_id2:
+ if (value != gzip::magic::id2)
+ throw gzip_error(gzip::bad_header);
+ state_ = s_cm;
+ break;
+ case s_cm:
+ if (value != gzip::method::deflate)
+ throw gzip_error(gzip::bad_method);
+ state_ = s_flg;
+ break;
+ case s_flg:
+ flags_ = value;
+ state_ = s_mtime;
+ break;
+ case s_mtime:
+ mtime_ += value << (offset_ * 8);
+ if (offset_ == 3) {
+ state_ = s_xfl;
+ offset_ = 0;
+ } else {
+ ++offset_;
+ }
+ break;
+ case s_xfl:
+ state_ = s_os;
+ break;
+ case s_os:
+ os_ = value;
+ if (flags_ & gzip::flags::extra) {
+ state_ = s_extra;
+ } else if (flags_ & gzip::flags::name) {
+ state_ = s_name;
+ } else if (flags_ & gzip::flags::comment) {
+ state_ = s_comment;
+ } else if (flags_ & gzip::flags::header_crc) {
+ state_ = s_hcrc;
+ } else {
+ state_ = s_done;
+ }
+ break;
+ case s_xlen:
+ xlen_ += value << (offset_ * 8);
+ if (offset_ == 1) {
+ state_ = s_extra;
+ offset_ = 0;
+ } else {
+ ++offset_;
+ }
+ break;
+ case s_extra:
+ if (--xlen_ == 0) {
+ if (flags_ & gzip::flags::name) {
+ state_ = s_name;
+ } else if (flags_ & gzip::flags::comment) {
+ state_ = s_comment;
+ } else if (flags_ & gzip::flags::header_crc) {
+ state_ = s_hcrc;
+ } else {
+ state_ = s_done;
+ }
+ }
+ break;
+ case s_name:
+ if (c != 0) {
+ file_name_ += c;
+ } else if (flags_ & gzip::flags::comment) {
+ state_ = s_comment;
+ } else if (flags_ & gzip::flags::header_crc) {
+ state_ = s_hcrc;
+ } else {
+ state_ = s_done;
+ }
+ break;
+ case s_comment:
+ if (c != 0) {
+ comment_ += c;
+ } else if (flags_ & gzip::flags::header_crc) {
+ state_ = s_hcrc;
+ } else {
+ state_ = s_done;
+ }
+ break;
+ case s_hcrc:
+ if (offset_ == 1) {
+ state_ = s_done;
+ offset_ = 0;
+ } else {
+ ++offset_;
+ }
+ break;
+ default:
+ assert(0);
+ }
+}
+
+void gzip_header::reset()
+{
+ file_name_.clear();
+ comment_.clear();
+ os_ = flags_ = offset_ = xlen_ = 0;
+ mtime_ = 0;
+ state_ = s_id1;
+}
+
+//------------------Implementation of gzip_footer-----------------------------//
+
+void gzip_footer::process(char c)
+{
+ uint8_t value = static_cast<uint8_t>(c);
+ if (state_ == s_crc) {
+ crc_ += value << (offset_ * 8);
+ if (offset_ == 3) {
+ state_ = s_isize;
+ offset_ = 0;
+ } else {
+ ++offset_;
+ }
+ } else if (state_ == s_isize) {
+ isize_ += value << (offset_ * 8);
+ if (offset_ == 3) {
+ state_ = s_done;
+ offset_ = 0;
+ } else {
+ ++offset_;
+ }
+ } else {
+ assert(0);
+ }
+}
+
+void gzip_footer::reset()
+{
+ crc_ = isize_ = offset_ = 0;
+ state_ = s_crc;
+}
+
+} // End namespace boost::iostreams::detail.
+
+} } // End namespaces iostreams, boost.
Modified: branches/release/libs/iostreams/src/mapped_file.cpp
==============================================================================
--- branches/release/libs/iostreams/src/mapped_file.cpp (original)
+++ branches/release/libs/iostreams/src/mapped_file.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -1,12 +1,7 @@
-// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
-// (C) Copyright 2004-2007 Jonathan Turkanis
// (C) Copyright Craig Henderson 2002 'boost/memmap.hpp' from sandbox
+// (C) Copyright Jonathan Turkanis 2004.
// (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.
+// (C) Copyright Jorge Lodos 2008.
// Define BOOST_IOSTREAMS_SOURCE so that <boost/iostreams/detail/config.hpp>
// knows that we are building the library (possibly exporting code), rather
@@ -14,21 +9,15 @@
#define BOOST_IOSTREAMS_SOURCE
#include <cassert>
-#ifndef NDEBUG
-# include <boost/iostreams/detail/absolute_path.hpp>
-#endif
-#include <boost/iostreams/detail/config/dyn_link.hpp>
+#include <boost/iostreams/detail/config/rtl.hpp>
#include <boost/iostreams/detail/config/windows_posix.hpp>
-#include <boost/iostreams/detail/ios.hpp> // failure.
+#include <boost/iostreams/detail/file_handle.hpp>
#include <boost/iostreams/detail/system_failure.hpp>
#include <boost/iostreams/device/mapped_file.hpp>
#ifdef BOOST_IOSTREAMS_WINDOWS
# define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
# include <windows.h>
-# ifndef INVALID_SET_FILE_POINTER
-# define INVALID_SET_FILE_POINTER ((DWORD)-1)
-# endif
#else
# include <errno.h>
# include <fcntl.h>
@@ -38,423 +27,454 @@
# include <unistd.h> // sysconf.
#endif
-#include <boost/iostreams/detail/config/disable_warnings.hpp>
-
namespace boost { namespace iostreams {
namespace detail {
-struct mapped_file_impl {
- mapped_file_impl() { clear(false); }
- ~mapped_file_impl() { try { close(); } catch (...) { } }
- void clear(bool error)
- {
- data_ = 0;
- size_ = 0;
- mode_ = BOOST_IOS::openmode();
- error_ = error;
- #ifdef BOOST_IOSTREAMS_WINDOWS
- handle_ = INVALID_HANDLE_VALUE;
- mapped_handle_ = NULL;
- #else
- handle_ = 0;
- #endif
- #ifndef NDEBUG
- path_.erase();
- #endif
- }
- void close()
- {
- bool error = false;
- #ifdef BOOST_IOSTREAMS_WINDOWS
- if (handle_ == INVALID_HANDLE_VALUE)
- return;
- error = !::UnmapViewOfFile(data_) || error;
- error = !::CloseHandle(mapped_handle_) || error;
- error = !::CloseHandle(handle_) || error;
- handle_ = INVALID_HANDLE_VALUE;
- mapped_handle_ = NULL;
- #else
- if (!handle_)
- return;
- error = ::munmap(reinterpret_cast<char*>(data_), size_) != 0 || error;
- error = ::close(handle_) != 0 || error;
- handle_ = 0;
- #endif
- data_ = 0;
- size_ = 0;
- mode_ = BOOST_IOS::openmode();
- if (error) {
- std::string msg("error closing mapped file");
- #ifndef NDEBUG
- msg += std::string(" (\"") + path_ + "\")";
- #endif
- throw_system_failure(msg);
- }
- #ifndef NDEBUG
- path_.erase();
- #endif
- }
- char* data_;
- std::size_t size_;
- BOOST_IOS::openmode mode_;
- bool error_;
+// Class containing the platform-sepecific implementation
+// Invariant: The members params_, data_, size_, handle_ (and mapped_handle_
+// on Windows) either
+// - all have default values (or INVALID_HANDLE_VALUE for
+// Windows handles), or
+// - all have values reflecting a successful mapping.
+// In the first case, error_ may be true, reflecting a recent unsuccessful
+// open or close attempt; in the second case, error_ is always false.
+class mapped_file_impl {
+public:
+ typedef mapped_file_source::size_type size_type;
+ typedef mapped_file_source::param_type param_type;
+ typedef mapped_file_source::mapmode mapmode;
+ BOOST_STATIC_CONSTANT(
+ size_type, max_length = mapped_file_source::max_length);
+ mapped_file_impl();
+ ~mapped_file_impl();
+ void open(param_type p);
+ bool is_open() const { return data_ != 0; }
+ void close();
+ bool error() const { return error_; }
+ mapmode flags() const { return params_.flags; }
+ std::size_t size() const { return size_; }
+ char* data() const { return data_; }
+ void resize(stream_offset new_size);
+ static int alignment();
+private:
+ void open_file(param_type p);
+ void try_map_file(param_type p);
+ void map_file(param_type& p);
+ bool unmap_file();
+ void clear(bool error);
+ void cleanup_and_throw(const char* msg);
+ param_type params_;
+ char* data_;
+ stream_offset size_;
+ file_handle handle_;
#ifdef BOOST_IOSTREAMS_WINDOWS
- HANDLE handle_;
- HANDLE mapped_handle_;
-#else
- int handle_;
-#endif
-#ifndef NDEBUG
- std::string path_;
+ file_handle mapped_handle_;
#endif
+ bool error_;
};
-} // End namespace detail.
-
-//------------------Definition of mapped_file_source--------------------------//
+mapped_file_impl::mapped_file_impl() { clear(false); }
-mapped_file_source::mapped_file_source(mapped_file_params p) { open(p); }
+mapped_file_impl::~mapped_file_impl()
+{ try { close(); } catch (...) { } }
-mapped_file_source::mapped_file_source( const std::string& path,
- mapped_file_source::size_type length,
- boost::intmax_t offset )
-{ open(path, length, offset); }
-
-void mapped_file_source::open(mapped_file_params p)
+void mapped_file_impl::open(param_type p)
{
- p.mode &= ~BOOST_IOS::out;
- open_impl(p);
-}
-
-void mapped_file_source::open( const std::string& path,
- mapped_file_source::size_type length,
- boost::intmax_t offset )
-{
- mapped_file_params p(path);
- p.mode = BOOST_IOS::in;
- p.length = length;
- p.offset = offset;
- open_impl(p);
+ if (is_open())
+ throw BOOST_IOSTREAMS_FAILURE("file already open");
+ p.normalize();
+ open_file(p);
+ map_file(p); // May modify p.hint
+ params_ = p;
+}
+
+void mapped_file_impl::close()
+{
+ if (data_ == 0)
+ return;
+ bool error = false;
+ error = !unmap_file() || error;
+ error =
+ #ifdef BOOST_IOSTREAMS_WINDOWS
+ !::CloseHandle(handle_)
+ #else
+ ::close(handle_) != 0
+ #endif
+ || error;
+ clear(error);
+ if (error)
+ throw_system_failure("failed closing mapped file");
+}
+
+void mapped_file_impl::resize(stream_offset new_size)
+{
+ if (!is_open())
+ throw BOOST_IOSTREAMS_FAILURE("file is closed");
+ if (flags() & mapped_file::priv)
+ throw BOOST_IOSTREAMS_FAILURE("can't resize private mapped file");
+ if (!(flags() & mapped_file::readwrite))
+ throw BOOST_IOSTREAMS_FAILURE("can't resize readonly mapped file");
+ if (params_.offset >= new_size)
+ throw BOOST_IOSTREAMS_FAILURE("can't resize below mapped offset");
+ if (!unmap_file())
+ cleanup_and_throw("failed unmapping file");
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ stream_offset offset = ::SetFilePointer(handle_, 0, NULL, FILE_CURRENT);
+ if (::GetLastError() != NO_ERROR)
+ cleanup_and_throw("failed querying file pointer");
+ LONG sizehigh = (new_size >> (sizeof(LONG) * 8));
+ LONG sizelow = (new_size & 0xffffffff);
+ ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
+ if (::GetLastError() != NO_ERROR || !::SetEndOfFile(handle_))
+ cleanup_and_throw("failed resizing mapped file");
+ sizehigh = (offset >> (sizeof(LONG) * 8));
+ sizelow = (offset & 0xffffffff);
+ ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
+#else
+ if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, new_size) == -1)
+ cleanup_and_throw("failed resizing mapped file");
+#endif
+ size_ = new_size;
+ param_type p(params_);
+ map_file(p); // May modify p.hint
+ params_ = p;
}
-mapped_file_source::size_type mapped_file_source::size() const
-{ return pimpl_->size_; }
-
-void mapped_file_source::close() { pimpl_->close(); }
-
-mapped_file_source::operator mapped_file_source::safe_bool() const
+int mapped_file_impl::alignment()
{
- return !!pimpl_ && pimpl_->error_ == false ?
- &safe_bool_helper::x : 0;
-}
-
-bool mapped_file_source::operator!() const
-{ return !!pimpl_ || pimpl_->error_; }
-
-BOOST_IOS::openmode mapped_file_source::mode() const { return pimpl_->mode_; }
-
-const char* mapped_file_source::data() const { return pimpl_->data_; }
-
-const char* mapped_file_source::begin() const { return data(); }
-
-const char* mapped_file_source::end() const { return data() + size(); }
-
-#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
-
-namespace detail {
-
-void cleanup_and_throw(detail::mapped_file_impl& impl, std::string msg)
-{
- #ifndef NDEBUG
- msg += std::string(" (\"") + impl.path_ + "\")";
- #endif
- if (impl.mapped_handle_ != INVALID_HANDLE_VALUE)
- ::CloseHandle(impl.mapped_handle_);
- if (impl.handle_ != NULL)
- ::CloseHandle(impl.handle_);
- impl.clear(true);
- throw_system_failure(msg);
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ SYSTEM_INFO info;
+ ::GetSystemInfo(&info);
+ return static_cast<int>(info.dwAllocationGranularity);
+#else
+ return static_cast<int>(sysconf(_SC_PAGESIZE));
+#endif
}
-} // End namespace detail.
-
-void mapped_file_source::open_impl(mapped_file_params p)
+void mapped_file_impl::open_file(param_type p)
{
- using namespace std;
-
- if (is_open())
- throw BOOST_IOSTREAMS_FAILURE("file already open");
- if (!pimpl_)
- pimpl_.reset(new impl_type);
- else
- pimpl_->clear(false);
- bool readonly = (p.mode & BOOST_IOS::out) == 0;
- pimpl_->mode_ = readonly ? BOOST_IOS::in : (BOOST_IOS::in | BOOST_IOS::out);
- #ifndef NDEBUG
- pimpl_->path_ = detail::absolute_path(p.path);
- #endif
-
- //--------------Open underlying file--------------------------------------//
-
- pimpl_->handle_ =
- ::CreateFileA( p.path.c_str(),
- readonly ? GENERIC_READ : GENERIC_ALL,
- FILE_SHARE_READ,
- NULL,
- (p.new_file_size != 0 && !readonly) ?
- CREATE_ALWAYS :
- OPEN_EXISTING,
- readonly ?
- FILE_ATTRIBUTE_READONLY :
- FILE_ATTRIBUTE_TEMPORARY,
- NULL );
-
- if (pimpl_->handle_ == INVALID_HANDLE_VALUE) {
- detail::cleanup_and_throw(*pimpl_, "failed opening file");
- }
+ bool readonly = p.flags != mapped_file::readwrite;
+#ifdef BOOST_IOSTREAMS_WINDOWS
- //--------------Set file size---------------------------------------------//
+ // Open file
+ DWORD dwDesiredAccess = readonly ? GENERIC_READ : GENERIC_ALL;
+ DWORD dwCreationDisposition = (p.new_file_size != 0 && !readonly) ?
+ CREATE_ALWAYS :
+ OPEN_EXISTING;
+ DWORD dwFlagsandAttributes =
+ readonly ?
+ FILE_ATTRIBUTE_READONLY :
+ FILE_ATTRIBUTE_TEMPORARY;
+ handle_ = p.path.is_wide() ?
+ ::CreateFileW(
+ p.path.c_wstr(),
+ dwDesiredAccess,
+ FILE_SHARE_READ,
+ NULL,
+ dwCreationDisposition,
+ dwFlagsandAttributes,
+ NULL ) :
+ ::CreateFileA(
+ p.path.c_str(),
+ dwDesiredAccess,
+ FILE_SHARE_READ,
+ NULL,
+ dwCreationDisposition,
+ dwFlagsandAttributes,
+ NULL );
+ if (handle_ == INVALID_HANDLE_VALUE)
+ cleanup_and_throw("failed opening file");
+ // Set file size
if (p.new_file_size != 0 && !readonly) {
LONG sizehigh = (p.new_file_size >> (sizeof(LONG) * 8));
LONG sizelow = (p.new_file_size & 0xffffffff);
- DWORD result =
- ::SetFilePointer(pimpl_->handle_, sizelow, &sizehigh, FILE_BEGIN);
- if ( result == INVALID_SET_FILE_POINTER &&
- ::GetLastError() != NO_ERROR ||
- !::SetEndOfFile(pimpl_->handle_) )
- {
- detail::cleanup_and_throw(*pimpl_, "failed setting file size");
- }
- }
-
- //--------------Create mapping--------------------------------------------//
-
- try_again: // Target of goto in following section.
-
- pimpl_->mapped_handle_ =
- ::CreateFileMappingA( pimpl_->handle_, NULL,
- readonly ? PAGE_READONLY : PAGE_READWRITE,
- 0, 0, NULL );
- if (pimpl_->mapped_handle_ == NULL) {
- detail::cleanup_and_throw(*pimpl_, "couldn't create mapping");
+ ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
+ if (::GetLastError() != NO_ERROR || !::SetEndOfFile(handle_))
+ cleanup_and_throw("failed setting file size");
}
- //--------------Access data-----------------------------------------------//
-
- void* data =
- ::MapViewOfFileEx( pimpl_->mapped_handle_,
- readonly ? FILE_MAP_READ : FILE_MAP_WRITE,
- (DWORD) (p.offset >> 32),
- (DWORD) (p.offset & 0xffffffff),
- p.length != max_length ? p.length : 0, (LPVOID) p.hint );
- if (!data) {
- if (p.hint != 0) {
- p.hint = 0;
- goto try_again;
- }
- detail::cleanup_and_throw(*pimpl_, "failed mapping view");
- }
-
- //--------------Determing file size---------------------------------------//
-
- // Dynamically locate GetFileSizeEx (thanks to Pavel Vozenilik).
+ // Determine file size. Dynamically locate GetFileSizeEx for compatibility
+ // with old Platform SDK (thanks to Pavel Vozenilik).
typedef BOOL (WINAPI *func)(HANDLE, PLARGE_INTEGER);
HMODULE hmod = ::GetModuleHandleA("kernel32.dll");
func get_size =
reinterpret_cast<func>(::GetProcAddress(hmod, "GetFileSizeEx"));
-
if (get_size) {
LARGE_INTEGER info;
- if (get_size(pimpl_->handle_, &info)) {
+ if (get_size(handle_, &info)) {
boost::intmax_t size =
( (static_cast<boost::intmax_t>(info.HighPart) << 32) |
info.LowPart );
- pimpl_->size_ =
+ size_ =
static_cast<std::size_t>(
p.length != max_length ?
std::min<boost::intmax_t>(p.length, size) :
size
);
} else {
- detail::cleanup_and_throw(*pimpl_, "failed getting file size");
+ cleanup_and_throw("failed querying file size");
return;
}
} else {
DWORD hi;
DWORD low;
- if ( (low = ::GetFileSize(pimpl_->handle_, &hi))
+ if ( (low = ::GetFileSize(handle_, &hi))
!=
INVALID_FILE_SIZE )
{
boost::intmax_t size =
(static_cast<boost::intmax_t>(hi) << 32) | low;
- pimpl_->size_ =
+ size_ =
static_cast<std::size_t>(
p.length != max_length ?
std::min<boost::intmax_t>(p.length, size) :
size
);
} else {
- detail::cleanup_and_throw(*pimpl_, "failed getting file size");
+ cleanup_and_throw("failed querying file size");
return;
}
}
+#else // #ifdef BOOST_IOSTREAMS_WINDOWS
- pimpl_->data_ = reinterpret_cast<char*>(data);
-}
-
-bool mapped_file_source::is_open() const
-{ return !!pimpl_ && pimpl_->handle_ != INVALID_HANDLE_VALUE; }
-
-int mapped_file_source::alignment()
-{
- SYSTEM_INFO info;
- ::GetSystemInfo(&info);
- return static_cast<int>(info.dwAllocationGranularity);
-}
-
-#else // #ifdef BOOST_IOSTREAMS_WINDOWS //------------------------------------//
-
-namespace detail {
-
- void cleanup_and_throw(detail::mapped_file_impl& impl, std::string msg)
-{
- #ifndef NDEBUG
- msg += std::string(" (\"") + impl.path_ + "\")";
- #endif
- if (impl.handle_ != 0)
- ::close(impl.handle_);
- impl.clear(true);
- throw_system_failure(msg);
-}
-
-} // End namespace detail.
-
-
-void mapped_file_source::open_impl(mapped_file_params p)
-{
- using namespace std;
-
- if (is_open())
- throw BOOST_IOSTREAMS_FAILURE("file already open");
- if (!pimpl_)
- pimpl_.reset(new impl_type);
- else
- pimpl_->clear(false);
- bool readonly = (p.mode & BOOST_IOS::out) == 0;
- pimpl_->mode_ = readonly ? BOOST_IOS::in : (BOOST_IOS::in | BOOST_IOS::out);
- #ifndef NDEBUG
- pimpl_->path_ = detail::absolute_path(p.path);
- #endif
-
- //--------------Open underlying file--------------------------------------//
-
+ // Open file
int flags = (readonly ? O_RDONLY : O_RDWR);
if (p.new_file_size != 0 && !readonly)
flags |= (O_CREAT | O_TRUNC);
+ #ifdef _LARGEFILE64_SOURCE
+ flags |= O_LARGEFILE;
+ #endif
errno = 0;
- pimpl_->handle_ = ::open(p.path.c_str(), flags, S_IRWXU);
+ handle_ = ::open(p.path.c_str(), flags, S_IRWXU);
if (errno != 0)
- detail::cleanup_and_throw(*pimpl_, "failed opening file");
+ cleanup_and_throw("failed opening file");
//--------------Set file size---------------------------------------------//
if (p.new_file_size != 0 && !readonly)
- if (ftruncate(pimpl_->handle_, p.new_file_size) == -1)
- detail::cleanup_and_throw(*pimpl_, "failed setting file size");
+ if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, p.new_file_size) == -1)
+ cleanup_and_throw("failed setting file size");
//--------------Determine file size---------------------------------------//
bool success = true;
- struct stat info;
- if (p.length != max_length)
- pimpl_->size_ = p.length;
- else {
- success = ::fstat(pimpl_->handle_, &info) != -1;
- pimpl_->size_ = info.st_size;
+ if (p.length != max_length) {
+ size_ = p.length;
+ } else {
+ struct BOOST_IOSTREAMS_FD_STAT info;
+ success = ::BOOST_IOSTREAMS_FD_FSTAT(handle_, &info) != -1;
+ size_ = info.st_size;
}
if (!success)
- detail::cleanup_and_throw(*pimpl_, "failed getting file size");
+ cleanup_and_throw("failed querying file size");
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+}
- //--------------Create mapping--------------------------------------------//
+void mapped_file_impl::try_map_file(param_type p)
+{
+ bool priv = p.flags == mapped_file::priv;
+ bool readonly = p.flags == mapped_file::readonly;
+#ifdef BOOST_IOSTREAMS_WINDOWS
- try_again: // Target of goto in following section.
+ // Create mapping
+ DWORD protect = priv ?
+ PAGE_WRITECOPY :
+ readonly ?
+ PAGE_READONLY :
+ PAGE_READWRITE;
+ mapped_handle_ =
+ ::CreateFileMappingA(
+ handle_,
+ NULL,
+ protect,
+ 0,
+ 0,
+ NULL );
+ if (mapped_handle_ == NULL)
+ cleanup_and_throw("failed create mapping");
+
+ // Access data
+ DWORD access = priv ?
+ FILE_MAP_COPY :
+ readonly ?
+ FILE_MAP_READ :
+ FILE_MAP_WRITE;
+ void* data =
+ ::MapViewOfFileEx(
+ mapped_handle_,
+ access,
+ (DWORD) (p.offset >> 32),
+ (DWORD) (p.offset & 0xffffffff),
+ size_ != max_length ? size_ : 0,
+ (LPVOID) p.hint );
+ if (!data)
+ cleanup_and_throw("failed mapping view");
+#else
+ void* data =
+ ::BOOST_IOSTREAMS_FD_MMAP(
+ const_cast<char*>(p.hint),
+ size_,
+ readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
+ priv ? MAP_PRIVATE : MAP_SHARED,
+ handle_,
+ p.offset );
+ if (data == MAP_FAILED)
+ cleanup_and_throw("failed mapping file");
+#endif
+ data_ = static_cast<char*>(data);
+}
- char* hint = const_cast<char*>(p.hint);
- void* data = ::mmap( hint, pimpl_->size_,
- readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
- readonly ? MAP_PRIVATE : MAP_SHARED,
- pimpl_->handle_, p.offset );
- if (data == MAP_FAILED) {
- if (hint != 0) {
- hint = 0;
- goto try_again;
+void mapped_file_impl::map_file(param_type& p)
+{
+ try {
+ try_map_file(p);
+ } catch (const std::exception& e) {
+ if (p.hint) {
+ p.hint = 0;
+ try_map_file(p);
+ } else {
+ throw e;
}
- detail::cleanup_and_throw(*pimpl_, "failed mapping file");
}
- pimpl_->data_ = reinterpret_cast<char*>(data);
+}
+
+bool mapped_file_impl::unmap_file()
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ bool error = false;
+ error = !::UnmapViewOfFile(data_) || error;
+ error = !::CloseHandle(mapped_handle_) || error;
+ mapped_handle_ = NULL;
+ return !error;
+#else
+ return ::munmap(data_, size_) == 0;
+#endif
+}
+
+void mapped_file_impl::clear(bool error)
+{
+ params_ = param_type();
+ data_ = 0;
+ size_ = 0;
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ handle_ = INVALID_HANDLE_VALUE;
+ mapped_handle_ = NULL;
+#else
+ handle_ = 0;
+#endif
+ error_ = error;
+}
- return;
+// Called when an error is encountered during the execution of open_file or
+// map_file
+void mapped_file_impl::cleanup_and_throw(const char* msg)
+{
+#ifdef BOOST_IOSTREAMS_WINDOWS
+ DWORD error = GetLastError();
+ if (mapped_handle_ != INVALID_HANDLE_VALUE)
+ ::CloseHandle(mapped_handle_);
+ if (handle_ != NULL)
+ ::CloseHandle(handle_);
+ SetLastError(error);
+#else
+ int error = errno;
+ if (handle_ != 0)
+ ::close(handle_);
+ errno = error;
+#endif
+ clear(true);
+ boost::iostreams::detail::throw_system_failure(msg);
}
+//------------------Implementation of mapped_file_params_base-----------------//
+
+void mapped_file_params_base::normalize()
+{
+ if (mode && flags)
+ throw BOOST_IOSTREAMS_FAILURE(
+ "at most one of 'mode' and 'flags' may be specified"
+ );
+ if (flags) {
+ switch (flags) {
+ case mapped_file::readonly:
+ case mapped_file::readwrite:
+ case mapped_file::priv:
+ break;
+ default:
+ throw BOOST_IOSTREAMS_FAILURE("invalid flags");
+ }
+ } else {
+ flags = (mode & BOOST_IOS::out) ?
+ mapped_file::readwrite :
+ mapped_file::readonly;
+ mode = BOOST_IOS::openmode();
+ }
+ if (offset < 0)
+ throw BOOST_IOSTREAMS_FAILURE("invalid offset");
+ if (new_file_size < 0)
+ throw BOOST_IOSTREAMS_FAILURE("invalid new file size");
+}
+
+} // End namespace detail.
+
+//------------------Implementation of mapped_file_source----------------------//
+
+mapped_file_source::mapped_file_source()
+ : pimpl_(new impl_type)
+ { }
+
+mapped_file_source::mapped_file_source(const mapped_file_source& other)
+ : pimpl_(other.pimpl_)
+ { }
+
bool mapped_file_source::is_open() const
-{ return !!pimpl_ && pimpl_->handle_ != 0; }
+{ return pimpl_->is_open(); }
-int mapped_file_source::alignment()
-{ return static_cast<int>(sysconf(_SC_PAGESIZE)); }
+void mapped_file_source::close() { pimpl_->close(); }
-#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+// safe_bool is explicitly qualified below to please msvc 7.1
+mapped_file_source::operator mapped_file_source::safe_bool() const
+{ return pimpl_->error() ? &safe_bool_helper::x : 0; }
-//------------------Implementation of mapped_file-----------------------------//
+bool mapped_file_source::operator!() const
+{ return pimpl_->error(); }
-mapped_file::mapped_file(mapped_file_params p) { delegate_.open_impl(p); }
+mapped_file_source::mapmode mapped_file_source::flags() const
+{ return pimpl_->flags(); }
-mapped_file::mapped_file( const std::string& path, BOOST_IOS::openmode mode,
- size_type length, stream_offset offset )
-{ open(path, mode, length, offset); }
-
-void mapped_file::open(mapped_file_params p)
-{ delegate_.open_impl(p); }
-
-void mapped_file::open( const std::string& path, BOOST_IOS::openmode mode,
- size_type length, stream_offset offset )
-{
- mapped_file_params p(path);
- p.mode = mode;
- p.length = length;
- p.offset = offset;
- open(p);
-}
+mapped_file_source::size_type mapped_file_source::size() const
+{ return pimpl_->size(); }
-//------------------Implementation of mapped_file_sink------------------------//
+const char* mapped_file_source::data() const { return pimpl_->data(); }
-mapped_file_sink::mapped_file_sink(mapped_file_params p) { open(p); }
+const char* mapped_file_source::begin() const { return data(); }
-mapped_file_sink::mapped_file_sink( const std::string& path,
- size_type length, stream_offset offset )
-{ open(path, length, offset); }
+const char* mapped_file_source::end() const { return data() + size(); }
+int mapped_file_source::alignment()
+{ return detail::mapped_file_impl::alignment(); }
-void mapped_file_sink::open(mapped_file_params p)
-{
- p.mode |= BOOST_IOS::out;
- p.mode &= ~BOOST_IOS::in;
- mapped_file::open(p);
-}
+void mapped_file_source::init() { pimpl_.reset(new impl_type); }
-void mapped_file_sink::open( const std::string& path, size_type length,
- stream_offset offset )
-{
- mapped_file_params p(path);
- p.mode = BOOST_IOS::out;
- p.length = length;
- p.offset = offset;
- open(p);
-}
+void mapped_file_source::open_impl(const param_type& p)
+{ pimpl_->open(p); }
+
+//------------------Implementation of mapped_file-----------------------------//
+
+mapped_file::mapped_file(const mapped_file& other)
+ : delegate_(other.delegate_)
+ { }
+
+void mapped_file::resize(stream_offset new_size)
+{ delegate_.pimpl_->resize(new_size); }
+
+//------------------Implementation of mapped_file_sink------------------------//
+
+mapped_file_sink::mapped_file_sink(const mapped_file_sink& other)
+ : mapped_file(static_cast<const mapped_file&>(other))
+ { }
//----------------------------------------------------------------------------//
} } // End namespaces iostreams, boost.
-
-#include <boost/iostreams/detail/config/enable_warnings.hpp>
Modified: branches/release/libs/iostreams/src/zlib.cpp
==============================================================================
--- branches/release/libs/iostreams/src/zlib.cpp (original)
+++ branches/release/libs/iostreams/src/zlib.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -128,12 +128,12 @@
dest_begin = next_out;
}
-int zlib_base::deflate(int flush)
+int zlib_base::xdeflate(int flush)
{
return ::deflate(static_cast<z_stream*>(stream_), flush);
}
-int zlib_base::inflate(int flush)
+int zlib_base::xinflate(int flush)
{
return ::inflate(static_cast<z_stream*>(stream_), flush);
}
@@ -154,7 +154,7 @@
void zlib_base::do_init
( const zlib_params& p, bool compress,
#if !BOOST_WORKAROUND(BOOST_MSVC, < 1300)
- zlib::alloc_func /* alloc */, zlib::free_func /* free*/,
+ zlib::xalloc_func /* alloc */, zlib::xfree_func /* free*/,
#endif
void* derived )
{
Modified: branches/release/libs/iostreams/test/Jamfile.v2
==============================================================================
--- branches/release/libs/iostreams/test/Jamfile.v2 (original)
+++ branches/release/libs/iostreams/test/Jamfile.v2 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -54,6 +54,9 @@
[ test-iostreams filtering_stream_test.cpp ]
[ test-iostreams finite_state_filter_test.cpp ]
[ test-iostreams flush_test.cpp ]
+ [ test-iostreams
+ grep_test.cpp
+ /boost/regex//boost_regex ]
[ test-iostreams invert_test.cpp ]
[ test-iostreams line_filter_test.cpp ]
[ test-iostreams mapped_file_test.cpp
Added: branches/release/libs/iostreams/test/bool_trait_test.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/iostreams/test/bool_trait_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,252 @@
+/*
+ * 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.
+ *
+ * Tests the boolean type traits defined in boost/iostreams/traits.hpp.
+ *
+ * File: libs/iostreams/test/bool_trait_test.cpp
+ * Date: Sun Feb 17 17:52:59 MST 2008
+ * Copyright: 2008 CodeRage, LLC
+ * Author: Jonathan Turkanis
+ * Contact: turkanis at coderage dot com
+ */
+
+#include <fstream>
+#include <sstream>
+#include <boost/iostreams/detail/iostream.hpp>
+#include <boost/iostreams/detail/streambuf/linked_streambuf.hpp>
+#include <boost/iostreams/detail/iostream.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/iostreams/filtering_streambuf.hpp>
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/stream_buffer.hpp>
+#include <boost/iostreams/traits.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost::iostreams;
+namespace io = boost::iostreams;
+using boost::unit_test::test_suite;
+
+typedef stream<array_source> array_istream;
+typedef stream<warray_source> array_wistream;
+typedef stream<array_sink> array_ostream;
+typedef stream<warray_sink> array_wostream;
+typedef stream<array> array_stream;
+typedef stream<warray> array_wstream;
+typedef stream_buffer<array> array_streambuf;
+typedef stream_buffer<warray> array_wstreambuf;
+
+typedef io::filtering_stream<seekable> filtering_iostream;
+typedef io::filtering_stream<seekable, wchar_t> filtering_wiostream;
+
+typedef io::detail::linked_streambuf<char> linkedbuf;
+typedef io::detail::linked_streambuf<wchar_t> wlinkedbuf;
+
+#define BOOST_CHECK_BOOL_TRAIT(trait, type, status) \
+ BOOST_CHECK(trait< type >::value == status)
+ /**/
+
+#define BOOST_CHECK_STREAM_TRAIT( \
+ trait, \
+ istream_, wistream_, ostream_, wostream_, \
+ iostream_, wiostream_, streambuf_, wstreambuf_, \
+ ifstream_, wifstream_, ofstream_, wofstream_, \
+ fstream_, wfstream_, filebuf_, wfilebuf_, \
+ istringstream_, wistringstream_, ostringstream_, wostringstream_, \
+ stringstream_, wstringstream_, stringbuf_, wstringbuf_, \
+ array_istream_, array_wistream_, array_ostream_, array_wostream_, \
+ array_stream_, array_wstream_, array_streambuf_, array_wstreambuf_, \
+ filtering_istream_, filtering_wistream_, \
+ filtering_ostream_, filtering_wostream_, \
+ filtering_iostream_, filtering_wiostream_, \
+ filtering_istreambuf_, filtering_wistreambuf_, \
+ linkedbuf_, wlinkedbuf_ ) \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::istream, istream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wistream, wistream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::ostream, ostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wostream, wostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::iostream, iostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wiostream, wiostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::streambuf, streambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wstreambuf, wstreambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wifstream, wifstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::ofstream, ofstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wofstream, wofstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::fstream, fstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wfstream, wfstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::filebuf, filebuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wfilebuf, wfilebuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::istringstream, istringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wistringstream, wistringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::ostringstream, ostringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wostringstream, wostringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::stringstream, stringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wstringstream, wstringstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::stringbuf, stringbuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, std::wstringbuf, wstringbuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_istream, array_istream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_wistream, array_wistream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_ostream, array_ostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_wostream, array_wostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_stream, array_stream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_wstream, array_wstream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_streambuf, array_streambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, array_wstreambuf, array_wstreambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_istream, filtering_istream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_wistream, filtering_wistream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_ostream, filtering_ostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_wostream, filtering_wostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, filtering_iostream, filtering_iostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, filtering_wiostream, filtering_wiostream_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_istreambuf, filtering_istreambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::filtering_wistreambuf, filtering_wistreambuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, linkedbuf, linkedbuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, wlinkedbuf, wlinkedbuf_); \
+ BOOST_CHECK_BOOL_TRAIT(trait, io::array, false); \
+ BOOST_CHECK_BOOL_TRAIT(trait, int, false);
+ /**/
+
+void bool_trait_test()
+{
+ // Test is_istream
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_istream,
+ true, true, false, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+ true, true, false, false, true, true, false, false,
+ false, false
+ );
+
+ // Test is_ostream
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_ostream,
+ false, false, true, true, true, true, false, false,
+ false, false, true, true, true, true, false, false,
+ false, false, true, true, true, true, false, false,
+ false, false, true, true, true, true, false, false,
+ false, false, true, true, true, true, false, false,
+ false, false
+ );
+
+ // Test is_iostream
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_iostream,
+ false, false, false, false, true, true, false, false,
+ false, false, false, false, true, true, false, false,
+ false, false, false, false, true, true, false, false,
+ false, false, false, false, true, true, false, false,
+ false, false, false, false, true, true, false, false,
+ false, false
+ );
+
+ // Test is_streambuf
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_streambuf,
+ false, false, false, false, false, false, true, true,
+ false, false, false, false, false, false, true, true,
+ false, false, false, false, false, false, true, true,
+ false, false, false, false, false, false, true, true,
+ false, false, false, false, false, false, true, true,
+ true, true
+ );
+
+ // Test is_std_io
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_std_io,
+ true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true,
+ true, true
+ );
+
+ // Test is_std_file_device
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_std_file_device,
+ false, false, false, false, false, false, false, false,
+ true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false
+ );
+
+ // Test is_std_string_device
+ BOOST_CHECK_STREAM_TRAIT(
+ io::is_std_string_device,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ true, true, true, true, true, true, true, true,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false
+ );
+
+ // Test is_boost_stream
+ BOOST_CHECK_STREAM_TRAIT(
+ io::detail::is_boost_stream,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ true, true, true, true, true, true, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false
+ );
+
+ // Test is_boost_stream_buffer
+ BOOST_CHECK_STREAM_TRAIT(
+ io::detail::is_boost_stream_buffer,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, true, true,
+ false, false, false, false, false, false, false, false,
+ false, false
+ );
+
+ // Test is_filtering_stream
+ BOOST_CHECK_STREAM_TRAIT(
+ io::detail::is_filtering_stream,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ true, true, true, true, true, true, false, false,
+ false, false
+ );
+
+ // Test is_filtering_streambuf
+ BOOST_CHECK_STREAM_TRAIT(
+ io::detail::is_filtering_streambuf,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, true, true,
+ false, false
+ );
+
+ // Test is_boost
+ BOOST_CHECK_STREAM_TRAIT(
+ io::detail::is_boost,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ false, false, false, false, false, false, false, false,
+ true, true, true, true, true, true, true, true,
+ true, true, true, true, true, true, true, true,
+ false, false
+ );
+}
+
+test_suite* init_unit_test_suite(int, char* [])
+{
+ test_suite* test = BOOST_TEST_SUITE("bool trait test");
+ test->add(BOOST_TEST_CASE(&bool_trait_test));
+ return test;
+}
Modified: branches/release/libs/iostreams/test/component_access_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/component_access_test.cpp (original)
+++ branches/release/libs/iostreams/test/component_access_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -39,7 +39,7 @@
void foo() { }
std::pair<char*, char*> input_sequence()
{
- return std::pair<char*, char*>(0, 0);
+ return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0));;
}
};
Modified: branches/release/libs/iostreams/test/detail/closable.hpp
==============================================================================
--- branches/release/libs/iostreams/test/detail/closable.hpp (original)
+++ branches/release/libs/iostreams/test/detail/closable.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -126,7 +126,7 @@
typedef direct_input category;
closable_device(operation close) : close_(close) { }
std::pair<char*, char*> input_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
void close() { close_.execute(); }
private:
operation close_;
@@ -140,7 +140,7 @@
typedef direct_output category;
closable_device(operation close) : close_(close) { }
std::pair<char*, char*> output_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
void close() { close_.execute(); }
private:
operation close_;
@@ -156,9 +156,9 @@
: close_input_(close_input), close_output_(close_output)
{ }
std::pair<char*, char*> input_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
std::pair<char*, char*> output_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
void close(BOOST_IOS::openmode which)
{
switch (which) {
@@ -185,9 +185,9 @@
typedef direct_seekable category;
closable_device(operation close) : close_(close) { }
std::pair<char*, char*> input_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
std::pair<char*, char*> output_sequence()
- { return std::pair<char*, char*>(0, 0); }
+ { return std::pair<char*, char*>(static_cast<char*>(0), static_cast<char*>(0)); }
void close() { close_.execute(); }
private:
operation close_;
Modified: branches/release/libs/iostreams/test/detail/operation_sequence.hpp
==============================================================================
--- branches/release/libs/iostreams/test/detail/operation_sequence.hpp (original)
+++ branches/release/libs/iostreams/test/detail/operation_sequence.hpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -150,8 +150,8 @@
{
using namespace std;
if ( error_code < 0 ||
- error_code > BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR &&
- error_code != INT_MAX )
+ (error_code > BOOST_IOSTREAMS_TEST_MAX_OPERATION_ERROR &&
+ error_code != INT_MAX) )
{
throw runtime_error( string("The error code ") +
lexical_cast<string>(error_code) +
Added: branches/release/libs/iostreams/test/grep_test.cpp
==============================================================================
--- (empty file)
+++ branches/release/libs/iostreams/test/grep_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -0,0 +1,282 @@
+/*
+ * 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: libs/iostreams/test/grep_test.cpp
+ * Date: Mon May 26 17:48:45 MDT 2008
+ * Copyright: 2008 CodeRage, LLC
+ * Author: Jonathan Turkanis
+ * Contact: turkanis at coderage dot com
+ *
+ * Tests the class template basic_grep_filter.
+ */
+
+#include <iostream>
+
+#include <boost/config.hpp> // Make sure ptrdiff_t is in std.
+#include <algorithm>
+#include <cstddef> // std::ptrdiff_t
+#include <string>
+#include <boost/iostreams/compose.hpp>
+#include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/device/back_inserter.hpp>
+#include <boost/iostreams/filter/grep.hpp>
+#include <boost/iostreams/filter/test.hpp>
+#include <boost/ref.hpp>
+#include <boost/regex.hpp>
+#include <boost/test/test_tools.hpp>
+#include <boost/test/unit_test.hpp>
+
+using namespace boost;
+using namespace boost::iostreams;
+namespace io = boost::iostreams;
+using boost::unit_test::test_suite;
+
+// List of addresses of US Appeals Courts, from uscourts.gov
+std::string addresses =
+ "John Joseph Moakley United States Courthouse, Suite 2500\n"
+ "One Courthouse Way\n"
+ "Boston, MA 02210-3002\n"
+ "\n"
+ "Thurgood Marshall United States Courthouse, 18th Floor\n"
+ "40 Centre Street\n"
+ "New York, NY 10007-1501\n"
+ "\n"
+ "21400 James A. Byrne United States Courthouse\n"
+ "601 Market Street\n"
+ "Philadelphia, PA 19106-1729\n"
+ "\n"
+ "Lewis F. Powell, Jr. United States Courthouse Annex, Suite 501\n"
+ "1100 East Main Street\n"
+ "Richmond, VA 23219-3525\n"
+ "\n"
+ "F. Edward Hebert Federal Bldg\n"
+ "600 South Maestri Place\n"
+ "New Orleans, LA 70130\n"
+ "\n"
+ "Bob Casey United States Courthouse, 1st Floor\n"
+ "515 Rusk Street\n"
+ "Houston, TX 77002-2600\n"
+ "\n"
+ "Potter Stewart United States Courthouse, Suite 540\n"
+ "100 East Fifth Street\n"
+ "Cincinnati, OH 45202\n"
+ "\n"
+ "2722 Everett McKinley Dirksen United States Courthouse\n"
+ "219 South Dearborn Street\n"
+ "Chicago, IL 60604\n";
+
+// Lines containing "United States Courthouse"
+std::string us_courthouse =
+ "John Joseph Moakley United States Courthouse, Suite 2500\n"
+ "Thurgood Marshall United States Courthouse, 18th Floor\n"
+ "21400 James A. Byrne United States Courthouse\n"
+ "Lewis F. Powell, Jr. United States Courthouse Annex, Suite 501\n"
+ "Bob Casey United States Courthouse, 1st Floor\n"
+ "Potter Stewart United States Courthouse, Suite 540\n"
+ "2722 Everett McKinley Dirksen United States Courthouse\n";
+
+// Lines not containing "United States Courthouse"
+std::string us_courthouse_inv =
+ "One Courthouse Way\n"
+ "Boston, MA 02210-3002\n"
+ "\n"
+ "40 Centre Street\n"
+ "New York, NY 10007-1501\n"
+ "\n"
+ "601 Market Street\n"
+ "Philadelphia, PA 19106-1729\n"
+ "\n"
+ "1100 East Main Street\n"
+ "Richmond, VA 23219-3525\n"
+ "\n"
+ "F. Edward Hebert Federal Bldg\n"
+ "600 South Maestri Place\n"
+ "New Orleans, LA 70130\n"
+ "\n"
+ "515 Rusk Street\n"
+ "Houston, TX 77002-2600\n"
+ "\n"
+ "100 East Fifth Street\n"
+ "Cincinnati, OH 45202\n"
+ "\n"
+ "219 South Dearborn Street\n"
+ "Chicago, IL 60604\n";
+
+// Lines containing a state and zip
+std::string state_and_zip =
+ "Boston, MA 02210-3002\n"
+ "New York, NY 10007-1501\n"
+ "Philadelphia, PA 19106-1729\n"
+ "Richmond, VA 23219-3525\n"
+ "New Orleans, LA 70130\n"
+ "Houston, TX 77002-2600\n"
+ "Cincinnati, OH 45202\n"
+ "Chicago, IL 60604\n";
+
+// Lines not containing a state and zip
+std::string state_and_zip_inv =
+ "John Joseph Moakley United States Courthouse, Suite 2500\n"
+ "One Courthouse Way\n"
+ "\n"
+ "Thurgood Marshall United States Courthouse, 18th Floor\n"
+ "40 Centre Street\n"
+ "\n"
+ "21400 James A. Byrne United States Courthouse\n"
+ "601 Market Street\n"
+ "\n"
+ "Lewis F. Powell, Jr. United States Courthouse Annex, Suite 501\n"
+ "1100 East Main Street\n"
+ "\n"
+ "F. Edward Hebert Federal Bldg\n"
+ "600 South Maestri Place\n"
+ "\n"
+ "Bob Casey United States Courthouse, 1st Floor\n"
+ "515 Rusk Street\n"
+ "\n"
+ "Potter Stewart United States Courthouse, Suite 540\n"
+ "100 East Fifth Street\n"
+ "\n"
+ "2722 Everett McKinley Dirksen United States Courthouse\n"
+ "219 South Dearborn Street\n";
+
+// Lines containing at least three words
+std::string three_words =
+ "John Joseph Moakley United States Courthouse, Suite 2500\n"
+ "One Courthouse Way\n"
+ "Thurgood Marshall United States Courthouse, 18th Floor\n"
+ "40 Centre Street\n"
+ "21400 James A. Byrne United States Courthouse\n"
+ "601 Market Street\n"
+ "Lewis F. Powell, Jr. United States Courthouse Annex, Suite 501\n"
+ "1100 East Main Street\n"
+ "F. Edward Hebert Federal Bldg\n"
+ "600 South Maestri Place\n"
+ "Bob Casey United States Courthouse, 1st Floor\n"
+ "515 Rusk Street\n"
+ "Potter Stewart United States Courthouse, Suite 540\n"
+ "100 East Fifth Street\n"
+ "2722 Everett McKinley Dirksen United States Courthouse\n"
+ "219 South Dearborn Street\n";
+
+// Lines containing exactly three words
+std::string exactly_three_words =
+ "One Courthouse Way\n"
+ "40 Centre Street\n"
+ "601 Market Street\n"
+ "515 Rusk Street\n";
+
+// Lines that don't contain exactly three words
+std::string exactly_three_words_inv =
+ "John Joseph Moakley United States Courthouse, Suite 2500\n"
+ "Boston, MA 02210-3002\n"
+ "\n"
+ "Thurgood Marshall United States Courthouse, 18th Floor\n"
+ "New York, NY 10007-1501\n"
+ "\n"
+ "21400 James A. Byrne United States Courthouse\n"
+ "Philadelphia, PA 19106-1729\n"
+ "\n"
+ "Lewis F. Powell, Jr. United States Courthouse Annex, Suite 501\n"
+ "1100 East Main Street\n"
+ "Richmond, VA 23219-3525\n"
+ "\n"
+ "F. Edward Hebert Federal Bldg\n"
+ "600 South Maestri Place\n"
+ "New Orleans, LA 70130\n"
+ "\n"
+ "Bob Casey United States Courthouse, 1st Floor\n"
+ "Houston, TX 77002-2600\n"
+ "\n"
+ "Potter Stewart United States Courthouse, Suite 540\n"
+ "100 East Fifth Street\n"
+ "Cincinnati, OH 45202\n"
+ "\n"
+ "2722 Everett McKinley Dirksen United States Courthouse\n"
+ "219 South Dearborn Street\n"
+ "Chicago, IL 60604\n";
+
+void test_filter( grep_filter grep,
+ const std::string& input,
+ const std::string& output );
+
+void grep_filter_test()
+{
+ regex match_us_courthouse("\\bUnited States Courthouse\\b");
+ regex match_state_and_zip("\\b[A-Z]{2}\\s+[0-9]{5}(-[0-9]{4})?\\b");
+ regex match_three_words("\\b\\w+\\s+\\w+\\s+\\w+\\b");
+ regex_constants::match_flag_type match_default =
+ regex_constants::match_default;
+
+ {
+ grep_filter grep(match_us_courthouse);
+ test_filter(grep, addresses, us_courthouse);
+ }
+
+ {
+ grep_filter grep(match_us_courthouse, match_default, grep::invert);
+ test_filter(grep, addresses, us_courthouse_inv);
+ }
+
+ {
+ grep_filter grep(match_state_and_zip);
+ test_filter(grep, addresses, state_and_zip);
+ }
+
+ {
+ grep_filter grep(match_state_and_zip, match_default, grep::invert);
+ test_filter(grep, addresses, state_and_zip_inv);
+ }
+
+ {
+ grep_filter grep(match_three_words);
+ test_filter(grep, addresses, three_words);
+ }
+
+ {
+ grep_filter grep(match_three_words, match_default, grep::whole_line);
+ test_filter(grep, addresses, exactly_three_words);
+ }
+
+ {
+ int options = grep::whole_line | grep::invert;
+ grep_filter grep(match_three_words, match_default, options);
+ test_filter(grep, addresses, exactly_three_words_inv);
+ }
+}
+
+void test_filter( grep_filter grep,
+ const std::string& input,
+ const std::string& output )
+{
+ // Count lines in output
+ ptrdiff_t count = std::count(output.begin(), output.end(), '\n');
+
+ // Test as input filter
+ {
+ array_source src(input.data(), input.data() + input.size());
+ std::string dest;
+ io::copy(compose(boost::ref(grep), src), io::back_inserter(dest));
+ BOOST_CHECK(dest == output);
+ BOOST_CHECK(grep.count() == count);
+ }
+
+ // Test as output filter
+ {
+ array_source src(input.data(), input.data() + input.size());
+ std::string dest;
+ io::copy(src, compose(boost::ref(grep), io::back_inserter(dest)));
+ BOOST_CHECK(dest == output);
+ BOOST_CHECK(grep.count() == count);
+ }
+}
+
+test_suite* init_unit_test_suite(int, char* [])
+{
+ test_suite* test = BOOST_TEST_SUITE("grep_filter test");
+ test->add(BOOST_TEST_CASE(&grep_filter_test));
+ return test;
+}
Modified: branches/release/libs/iostreams/test/gzip_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/gzip_test.cpp (original)
+++ branches/release/libs/iostreams/test/gzip_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -6,8 +6,14 @@
// See http://www.boost.org/libs/iostreams for documentation.
#include <string>
+#include <boost/iostreams/copy.hpp>
+#include <boost/iostreams/device/array.hpp>
+#include <boost/iostreams/device/back_inserter.hpp>
#include <boost/iostreams/filter/gzip.hpp>
#include <boost/iostreams/filter/test.hpp>
+#include <boost/iostreams/filtering_stream.hpp>
+#include <boost/ref.hpp>
+#include <boost/range/iterator_range.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
#include "detail/sequence.hpp"
@@ -16,18 +22,36 @@
using namespace boost;
using namespace boost::iostreams;
using namespace boost::iostreams::test;
+namespace io = boost::iostreams;
using boost::unit_test::test_suite;
struct gzip_alloc : std::allocator<char> { };
-void gzip_test()
+void compression_test()
{
- text_sequence data;
- BOOST_CHECK(
- test_filter_pair( gzip_compressor(),
- gzip_decompressor(),
- std::string(data.begin(), data.end()) )
- );
+ text_sequence data;
+
+ // Test compression and decompression with metadata
+ for (int i = 0; i < 4; ++i) {
+ gzip_params params;
+ if (i & 1) {
+ params.file_name = "original file name";
+ }
+ if (i & 2) {
+ params.comment = "detailed file description";
+ }
+ gzip_compressor out(params);
+ gzip_decompressor in;
+ BOOST_CHECK(
+ test_filter_pair( boost::ref(out),
+ boost::ref(in),
+ std::string(data.begin(), data.end()) )
+ );
+ BOOST_CHECK(in.file_name() == params.file_name);
+ BOOST_CHECK(in.comment() == params.comment);
+ }
+
+ // Test compression and decompression with custom allocator
BOOST_CHECK(
test_filter_pair( basic_gzip_compressor<gzip_alloc>(),
basic_gzip_decompressor<gzip_alloc>(),
@@ -35,9 +59,34 @@
);
}
+void multiple_member_test()
+{
+ text_sequence data;
+ std::vector<char> temp, dest;
+
+ // Write compressed data to temp, twice in succession
+ filtering_ostream out;
+ out.push(gzip_compressor());
+ out.push(io::back_inserter(temp));
+ io::copy(make_iterator_range(data), out);
+ out.push(io::back_inserter(temp));
+ io::copy(make_iterator_range(data), out);
+
+ // Read compressed data from temp into dest
+ filtering_istream in;
+ in.push(gzip_decompressor());
+ in.push(array_source(&temp[0], temp.size()));
+ io::copy(in, io::back_inserter(dest));
+
+ // Check that dest consists of two copies of data
+ BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin()));
+ BOOST_CHECK(std::equal(data.begin(), data.end(), dest.begin() + dest.size() / 2));
+}
+
test_suite* init_unit_test_suite(int, char* [])
{
test_suite* test = BOOST_TEST_SUITE("gzip test");
- test->add(BOOST_TEST_CASE(&gzip_test));
+ test->add(BOOST_TEST_CASE(&compression_test));
+ test->add(BOOST_TEST_CASE(&multiple_member_test));
return test;
}
Modified: branches/release/libs/iostreams/test/mapped_file_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/mapped_file_test.cpp (original)
+++ branches/release/libs/iostreams/test/mapped_file_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -1,33 +1,70 @@
-// (C) Copyright 2008 CodeRage, LLC (turkanis at coderage dot com)
-// (C) Copyright 2004-2007 Jonathan Turkanis
+// (C) Copyright Jorge Lodos 2008
+// (C) Copyright Jonathan Turkanis 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.
+// This is the original (boost 1.34) boost::iostream test for the mapped files with the
+// following modifications:
+// 1. The namespace for the mapped file was changed to seglib::filemap.
+// 2. Added test for privately mapped files.
+// 3. The test test_writeable was added for mapped files.
+// 4. The test test_resizeable was added for mapped files.
+//
+
#include <fstream>
#include <boost/config.hpp>
#include <boost/detail/workaround.hpp>
-#include <boost/iostreams/device/mapped_file.hpp>
-#include <boost/iostreams/stream.hpp>
#include <boost/test/test_tools.hpp>
#include <boost/test/unit_test.hpp>
+
+#include <boost/iostreams/stream.hpp>
+#include <boost/iostreams/device/mapped_file.hpp>
#include "detail/temp_file.hpp"
#include "detail/verification.hpp"
-using namespace std;
-using namespace boost;
-using namespace boost::iostreams;
-using namespace boost::iostreams::test;
-using boost::unit_test::test_suite;
-
// Code generation bugs cause tests to fail with global optimization.
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# pragma optimize("g", off)
#endif
+namespace boost { namespace iostreams { namespace test {
+
+bool test_writeable(mapped_file& mf)
+{
+ // Test writing
+ for (int i = 0; i < data_reps; ++i) {
+ memcpy(mf.data(), narrow_data(), chunk_size);
+ char buf[chunk_size];
+ memcpy(buf, mf.const_data(), chunk_size);
+ if (strncmp(buf, narrow_data(), chunk_size) != 0)
+ return false;
+ memset(mf.data(), 0, chunk_size);
+ }
+ return true;
+}
+
+bool test_resizeable(mapped_file& mf)
+{
+ // Test resizing
+ mapped_file::size_type size = mf.size();
+ if (size == 0)
+ return false;
+ mf.resize(size/2);
+ if (mf.size() != size/2)
+ return false;
+ mf.resize(size);
+ if (mf.size() != size)
+ return false;
+ return true;
+}
+
+} } } // End namespaces test, iostreams, boost.
+
void mapped_file_test()
{
+ using namespace boost::iostreams;
BOOST_MESSAGE("about to begin");
//--------------Reading from a mapped_file_source-------------------------//
@@ -38,13 +75,13 @@
// Test reading from a stream based on a mapped_file_source,
// in chars.
- test_file test1, test2;
- stream<mapped_file_source> first(test1.name());
+ boost::iostreams::test::test_file test1, test2;
+ boost::iostreams::stream<mapped_file_source> first(test1.name());
{
- ifstream second( test2.name().c_str(),
+ std::ifstream second( test2.name().c_str(),
BOOST_IOS::in | BOOST_IOS::binary );
BOOST_CHECK_MESSAGE(
- compare_streams_in_chars(first, second),
+ boost::iostreams::test::compare_streams_in_chars(first, second),
"failed reading from stream<mapped_file_source> in chars"
);
@@ -58,10 +95,10 @@
// in chunks. (Also tests reopening the stream.)
first.open(mapped_file_source(test1.name()));
{
- ifstream second( test2.name().c_str(),
+ std::ifstream second( test2.name().c_str(),
BOOST_IOS::in | BOOST_IOS::binary );
BOOST_CHECK_MESSAGE(
- compare_streams_in_chunks(first, second),
+ boost::iostreams::test::compare_streams_in_chunks(first, second),
"failed reading from stream<mapped_file_source> in chunks"
);
@@ -76,15 +113,15 @@
{
// Test writing to a stream based on a mapped_file_sink, in
// chars.
- uppercase_file first, second; // Will overwrite these.
- test_file test;
+ boost::iostreams::test::uppercase_file first, second; // Will overwrite these.
+ boost::iostreams::test::test_file test;
- stream<mapped_file_sink> out;
+ boost::iostreams::stream<mapped_file_sink> out;
out.open(mapped_file_sink(first.name()));
- write_data_in_chars(out);
+ boost::iostreams::test::write_data_in_chars(out);
out.close();
BOOST_CHECK_MESSAGE(
- compare_files(first.name(), test.name()),
+ boost::iostreams::test::compare_files(first.name(), test.name()),
"failed writing to stream<mapped_file_sink> in chars"
);
@@ -95,10 +132,10 @@
// Test writing to a stream based on a mapped_file_sink, in
// chunks. (Also tests reopening the stream.)
out.open(mapped_file_sink(second.name()));
- write_data_in_chunks(out);
+ boost::iostreams::test::write_data_in_chunks(out);
out.close();
BOOST_CHECK_MESSAGE(
- compare_files(second.name(), test.name()),
+ boost::iostreams::test::compare_files(second.name(), test.name()),
"failed writing to stream<mapped_file_sink> in chunks"
);
@@ -107,21 +144,21 @@
);
}
- //--------------Writing to a newly created file-----------------------------//
+ //--------------Writing to a newly created file---------------------------//
{
// Test writing to a newly created mapped file.
- temp_file first, second;
- test_file test;
+ boost::iostreams::test::temp_file first, second;
+ boost::iostreams::test::test_file test;
mapped_file_params p(first.name());
- p.new_file_size = data_reps * data_length();
- stream<mapped_file_sink> out;
+ p.new_file_size = boost::iostreams::test::data_reps * boost::iostreams::test::data_length();
+ boost::iostreams::stream<mapped_file_sink> out;
out.open(mapped_file_sink(p));
- write_data_in_chars(out);
+ boost::iostreams::test::write_data_in_chars(out);
out.close();
BOOST_CHECK_MESSAGE(
- compare_files(first.name(), test.name()),
+ boost::iostreams::test::compare_files(first.name(), test.name()),
"failed writing to newly created mapped file in chars"
);
@@ -130,10 +167,10 @@
// (Also tests reopening the stream.)
p.path = second.name();
out.open(mapped_file_sink(p));
- write_data_in_chunks(out);
+ boost::iostreams::test::write_data_in_chunks(out);
out.close();
BOOST_CHECK_MESSAGE(
- compare_files(second.name(), test.name()),
+ boost::iostreams::test::compare_files(second.name(), test.name()),
"failed writing to newly created mapped file in chunks"
);
}
@@ -143,11 +180,11 @@
{
// Test reading, writing and seeking within a stream based on a
// mapped_file, in chars.
- test_file test;
- stream<mapped_file> io;
+ boost::iostreams::test::test_file test;
+ boost::iostreams::stream<mapped_file> io;
io.open(mapped_file(test.name()));
BOOST_CHECK_MESSAGE(
- test_seekable_in_chars(io),
+ boost::iostreams::test::test_seekable_in_chars(io),
"failed seeking within stream<mapped_file> in chars"
);
@@ -162,7 +199,7 @@
// stream.)
io.open(mapped_file(test.name()));
BOOST_CHECK_MESSAGE(
- test_seekable_in_chunks(io),
+ boost::iostreams::test::test_seekable_in_chunks(io),
"failed seeking within stream<mapped_file> in chunks"
);
@@ -170,15 +207,74 @@
"done seeking within stream<mapped_file> in chunks"
);
}
+
+ //--------------Resizing a mapped_file------------------------------------//
+
+ {
+ // Test resizing a mapped_file.
+ boost::iostreams::test::test_file test;
+ mapped_file mf;
+ mf.open(test.name());
+ BOOST_CHECK_MESSAGE(
+ boost::iostreams::test::test_resizeable(mf),
+ "failed resizing a mapped_file"
+ );
+
+ BOOST_MESSAGE(
+ "done resizing a mapped_file"
+ );
+ }
+
+ //--------------Random access with a private mapped_file------------------//
+
+ {
+ // Use 2 copies of the file to compare later
+ boost::iostreams::test::test_file orig, copy;
+
+ // Test reading and writing within a mapped_file.
+ // Since the file is privately mapped, it should remain
+ // unchanged after writing when opened in readonly mode.
+ mapped_file mf;
+ mf.open(orig.name(), mapped_file::priv);
+ BOOST_CHECK_MESSAGE(
+ boost::iostreams::test::test_writeable(mf),
+ "failed seeking within private mapped_file"
+ );
+ BOOST_CHECK_MESSAGE(
+ boost::iostreams::test::compare_files(orig.name(), copy.name()),
+ "failed writing to private mapped_file"
+ );
+
+ BOOST_MESSAGE(
+ "done seeking within private mapped_file"
+ );
+
+ mf.close();
+
+ // Test reopening the mapped file.
+ mf.open(orig.name(), mapped_file::priv);
+ BOOST_CHECK_MESSAGE(
+ boost::iostreams::test::test_writeable(mf),
+ "failed reopening private mapped_file"
+ );
+ BOOST_CHECK_MESSAGE(
+ boost::iostreams::test::compare_files(orig.name(), copy.name()),
+ "failed writing to reopened private mapped_file"
+ );
+
+ BOOST_MESSAGE(
+ "done reopening private mapped_file"
+ );
+ }
}
#if BOOST_WORKAROUND(BOOST_MSVC, < 1300)
# pragma optimize("", on)
#endif
-test_suite* init_unit_test_suite(int, char* [])
+boost::unit_test::test_suite* init_unit_test_suite(int, char* [])
{
- test_suite* test = BOOST_TEST_SUITE("mapped_file test");
+ boost::unit_test::test_suite* test = BOOST_TEST_SUITE("mapped_file test");
test->add(BOOST_TEST_CASE(&mapped_file_test));
return test;
}
Modified: branches/release/libs/iostreams/test/tee_test.cpp
==============================================================================
--- branches/release/libs/iostreams/test/tee_test.cpp (original)
+++ branches/release/libs/iostreams/test/tee_test.cpp 2009-10-14 11:20:36 EDT (Wed, 14 Oct 2009)
@@ -27,6 +27,36 @@
void read_write_test()
{
{
+ test_file src1, src2;
+ temp_file dest;
+ filtering_istream first, second;
+ first.push(tee(file_sink(dest.name(), out_mode)));
+ first.push(file_source(src1.name(), in_mode));
+ second.push(file_source(src2.name(), in_mode));
+ compare_streams_in_chars(first, second); // ignore return value
+ first.reset();
+ BOOST_CHECK_MESSAGE(
+ compare_files(dest.name(), src1.name()),
+ "failed reading from a tee_filter in chars"
+ );
+ }
+
+ {
+ test_file src1, src2;
+ temp_file dest;
+ filtering_istream first, second;
+ first.push(tee(file_sink(dest.name(), out_mode)));
+ first.push(file_source(src1.name(), in_mode));
+ second.push(file_source(src2.name(), in_mode));
+ compare_streams_in_chunks(first, second); // ignore return value
+ first.reset();
+ BOOST_CHECK_MESSAGE(
+ compare_files(dest.name(), src1.name()),
+ "failed reading from a tee_filter in chunks"
+ );
+ }
+
+ {
temp_file dest1;
temp_file dest2;
filtering_ostream out;
@@ -55,6 +85,36 @@
}
{
+ test_file src1, src2;
+ temp_file dest;
+ filtering_istream first, second;
+ first.push( tee( file_source(src1.name(), in_mode),
+ file_sink(dest.name(), out_mode) ) );
+ second.push(file_source(src2.name(), in_mode));
+ compare_streams_in_chars(first, second); // ignore return value
+ first.reset();
+ BOOST_CHECK_MESSAGE(
+ compare_files(dest.name(), src1.name()),
+ "failed reading from a tee_device in chars"
+ );
+ }
+
+ {
+ test_file src1, src2;
+ temp_file dest;
+ filtering_istream first, second;
+ first.push( tee( file_source(src1.name(), in_mode),
+ file_sink(dest.name(), out_mode) ) );
+ second.push(file_source(src2.name(), in_mode));
+ compare_streams_in_chunks(first, second); // ignore return value
+ first.reset();
+ BOOST_CHECK_MESSAGE(
+ compare_files(dest.name(), src1.name()),
+ "failed reading from a tee_device in chunks"
+ );
+ }
+
+ {
temp_file dest1;
temp_file dest2;
filtering_ostream out;
Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk