Chris@16: // (C) Copyright Jorge Lodos 2008. Chris@16: // (C) Copyright Jonathan Turkanis 2003. Chris@16: // (C) Copyright Craig Henderson 2002. 'boost/memmap.hpp' from sandbox Chris@16: // Distributed under the Boost Software License, Version 1.0. (See accompanying Chris@16: // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) Chris@16: Chris@16: #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED Chris@16: #define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED Chris@16: Chris@16: #if defined(_MSC_VER) && (_MSC_VER >= 1020) Chris@16: # pragma once Chris@16: #endif Chris@16: Chris@16: #include // make sure size_t is in std. Chris@16: #include // size_t. Chris@16: #include // pathnames. Chris@16: #include // pair. Chris@16: #include // BOOST_MSVC. Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include // openmode, failure Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: #include Chris@16: Chris@16: // Must come last. Chris@16: #include Chris@16: Chris@16: namespace boost { namespace iostreams { Chris@16: Chris@16: //------------------Definition of mapped_file_base and mapped_file_params-----// Chris@16: Chris@16: // Forward declarations Chris@16: class mapped_file_source; Chris@16: class mapped_file_sink; Chris@16: class mapped_file; Chris@16: namespace detail { class mapped_file_impl; } Chris@16: Chris@16: class mapped_file_base { Chris@16: public: Chris@16: enum mapmode { Chris@16: readonly = 1, Chris@16: readwrite = 2, Chris@16: priv = 4 Chris@16: }; Chris@16: }; Chris@16: Chris@16: // Bitmask operations for mapped_file_base::mapmode Chris@16: mapped_file_base::mapmode Chris@16: operator|(mapped_file_base::mapmode a, mapped_file_base::mapmode b); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator~(mapped_file_base::mapmode a); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); Chris@16: Chris@16: mapped_file_base::mapmode Chris@16: operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b); Chris@16: Chris@16: //------------------Definition of mapped_file_params--------------------------// Chris@16: Chris@16: namespace detail { Chris@16: Chris@16: struct mapped_file_params_base { Chris@16: mapped_file_params_base() Chris@16: : flags(static_cast(0)), Chris@16: mode(), offset(0), length(static_cast(-1)), Chris@16: new_file_size(0), hint(0) Chris@16: { } Chris@16: private: Chris@16: friend class mapped_file_impl; Chris@16: void normalize(); Chris@16: public: Chris@16: mapped_file_base::mapmode flags; Chris@16: BOOST_IOS::openmode mode; // Deprecated Chris@16: stream_offset offset; Chris@16: std::size_t length; Chris@16: stream_offset new_file_size; Chris@16: const char* hint; Chris@16: }; Chris@16: Chris@16: } // End namespace detail. Chris@16: Chris@16: // This template allows Boost.Filesystem paths to be specified when creating or Chris@16: // reopening a memory mapped file, without creating a dependence on Chris@16: // Boost.Filesystem. Possible values of Path include std::string, Chris@16: // boost::filesystem::path, boost::filesystem::wpath, Chris@16: // and boost::iostreams::detail::path (used to store either a std::string or a Chris@16: // std::wstring). Chris@16: template Chris@16: struct basic_mapped_file_params Chris@16: : detail::mapped_file_params_base Chris@16: { Chris@16: typedef detail::mapped_file_params_base base_type; Chris@16: Chris@16: // For wide paths, instantiate basic_mapped_file_params Chris@16: // with boost::filesystem::wpath Chris@16: #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS Chris@16: BOOST_STATIC_ASSERT((!is_same::value)); Chris@16: #endif Chris@16: Chris@16: // Default constructor Chris@16: basic_mapped_file_params() { } Chris@16: Chris@16: // Construction from a Path Chris@16: explicit basic_mapped_file_params(const Path& p) : path(p) { } Chris@16: Chris@16: // Construction from a path of a different type Chris@16: template Chris@16: explicit basic_mapped_file_params(const PathT& p) : path(p) { } Chris@16: Chris@16: // Copy constructor Chris@16: basic_mapped_file_params(const basic_mapped_file_params& other) Chris@16: : base_type(other), path(other.path) Chris@16: { } Chris@16: Chris@16: // Templated copy constructor Chris@16: template Chris@16: basic_mapped_file_params(const basic_mapped_file_params& other) Chris@16: : base_type(other), path(other.path) Chris@16: { } Chris@16: Chris@16: typedef Path path_type; Chris@16: Path path; Chris@16: }; Chris@16: Chris@16: typedef basic_mapped_file_params mapped_file_params; Chris@16: Chris@16: //------------------Definition of mapped_file_source--------------------------// Chris@16: Chris@16: class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base { Chris@16: private: Chris@16: struct safe_bool_helper { int x; }; Chris@16: typedef int safe_bool_helper::* safe_bool; Chris@16: typedef detail::mapped_file_impl impl_type; Chris@16: typedef basic_mapped_file_params param_type; Chris@16: friend class mapped_file; Chris@16: friend class detail::mapped_file_impl; Chris@16: friend struct boost::iostreams::operations; Chris@16: public: Chris@16: typedef char char_type; Chris@16: struct category Chris@16: : public source_tag, Chris@16: public direct_tag, Chris@16: public closable_tag Chris@16: { }; Chris@16: typedef std::size_t size_type; Chris@16: typedef const char* iterator; Chris@16: BOOST_STATIC_CONSTANT(size_type, max_length = static_cast(-1)); Chris@16: Chris@16: // Default constructor Chris@16: mapped_file_source(); Chris@16: Chris@16: // Constructor taking a parameters object Chris@16: template Chris@16: explicit mapped_file_source(const basic_mapped_file_params& p); Chris@16: Chris@16: // Constructor taking a list of parameters Chris@16: template Chris@16: explicit mapped_file_source( const Path& path, Chris@16: size_type length = max_length, Chris@16: boost::intmax_t offset = 0 ); Chris@16: Chris@16: // Copy Constructor Chris@16: mapped_file_source(const mapped_file_source& other); Chris@16: Chris@16: //--------------Stream interface------------------------------------------// Chris@16: Chris@16: template Chris@16: void open(const basic_mapped_file_params& p); Chris@16: Chris@16: template Chris@16: void open( const Path& path, Chris@16: size_type length = max_length, Chris@16: boost::intmax_t offset = 0 ); Chris@16: Chris@16: bool is_open() const; Chris@16: void close(); Chris@16: operator safe_bool() const; Chris@16: bool operator!() const; Chris@16: mapmode flags() const; Chris@16: Chris@16: //--------------Container interface---------------------------------------// Chris@16: Chris@16: size_type size() const; Chris@16: const char* data() const; Chris@16: iterator begin() const; Chris@16: iterator end() const; Chris@16: Chris@16: //--------------Query admissible offsets----------------------------------// Chris@16: Chris@16: // Returns the allocation granularity for virtual memory. Values passed Chris@16: // as offsets must be multiples of this value. Chris@16: static int alignment(); Chris@16: Chris@16: private: Chris@16: void init(); Chris@16: void open_impl(const param_type& p); Chris@16: Chris@16: boost::shared_ptr pimpl_; Chris@16: }; Chris@16: Chris@16: //------------------Definition of mapped_file---------------------------------// Chris@16: Chris@16: class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base { Chris@16: private: Chris@16: typedef mapped_file_source delegate_type; Chris@16: typedef delegate_type::safe_bool safe_bool; Chris@16: typedef basic_mapped_file_params param_type; Chris@16: friend struct boost::iostreams::operations; Chris@16: friend class mapped_file_sink; Chris@16: public: Chris@16: typedef char char_type; Chris@16: struct category Chris@16: : public seekable_device_tag, Chris@16: public direct_tag, Chris@16: public closable_tag Chris@16: { }; Chris@16: typedef mapped_file_source::size_type size_type; Chris@16: typedef char* iterator; Chris@16: typedef const char* const_iterator; Chris@16: BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length); Chris@16: Chris@16: // Default constructor Chris@16: mapped_file() { } Chris@16: Chris@16: // Construstor taking a parameters object Chris@16: template Chris@16: explicit mapped_file(const basic_mapped_file_params& p); Chris@16: Chris@16: // Constructor taking a list of parameters Chris@16: template Chris@16: mapped_file( const Path& path, Chris@16: mapmode flags, Chris@16: size_type length = max_length, Chris@16: stream_offset offset = 0 ); Chris@16: Chris@16: // Constructor taking a list of parameters, including a Chris@16: // std::ios_base::openmode (deprecated) Chris@16: template Chris@16: explicit mapped_file( const Path& path, Chris@16: BOOST_IOS::openmode mode = Chris@16: BOOST_IOS::in | BOOST_IOS::out, Chris@16: size_type length = max_length, Chris@16: stream_offset offset = 0 ); Chris@16: Chris@16: // Copy Constructor Chris@16: mapped_file(const mapped_file& other); Chris@16: Chris@16: //--------------Conversion to mapped_file_source (deprecated)-------------// Chris@16: Chris@16: operator mapped_file_source&() { return delegate_; } Chris@16: operator const mapped_file_source&() const { return delegate_; } Chris@16: Chris@16: //--------------Stream interface------------------------------------------// Chris@16: Chris@16: // open overload taking a parameters object Chris@16: template Chris@16: void open(const basic_mapped_file_params& p); Chris@16: Chris@16: // open overload taking a list of parameters Chris@16: template Chris@16: void open( const Path& path, Chris@16: mapmode mode, Chris@16: size_type length = max_length, Chris@16: stream_offset offset = 0 ); Chris@16: Chris@16: // open overload taking a list of parameters, including a Chris@16: // std::ios_base::openmode (deprecated) Chris@16: template Chris@16: void open( const Path& path, Chris@16: BOOST_IOS::openmode mode = Chris@16: BOOST_IOS::in | BOOST_IOS::out, Chris@16: size_type length = max_length, Chris@16: stream_offset offset = 0 ); Chris@16: Chris@16: bool is_open() const { return delegate_.is_open(); } Chris@16: void close() { delegate_.close(); } Chris@16: operator safe_bool() const { return delegate_; } Chris@16: bool operator!() const { return !delegate_; } Chris@16: mapmode flags() const { return delegate_.flags(); } Chris@16: Chris@16: //--------------Container interface---------------------------------------// Chris@16: Chris@16: size_type size() const { return delegate_.size(); } Chris@16: char* data() const; Chris@16: const char* const_data() const { return delegate_.data(); } Chris@16: iterator begin() const { return data(); } Chris@16: const_iterator const_begin() const { return const_data(); } Chris@16: iterator end() const { return data() + size(); } Chris@16: const_iterator const_end() const { return const_data() + size(); } Chris@16: Chris@16: //--------------Query admissible offsets----------------------------------// Chris@16: Chris@16: // Returns the allocation granularity for virtual memory. Values passed Chris@16: // as offsets must be multiples of this value. Chris@16: static int alignment() { return mapped_file_source::alignment(); } Chris@16: Chris@16: //--------------File access----------------------------------------------// Chris@16: Chris@16: void resize(stream_offset new_size); Chris@16: private: Chris@16: delegate_type delegate_; Chris@16: }; Chris@16: Chris@16: //------------------Definition of mapped_file_sink----------------------------// Chris@16: Chris@16: class BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file { Chris@16: public: Chris@16: friend struct boost::iostreams::operations; Chris@16: using mapped_file::mapmode; Chris@16: using mapped_file::readonly; Chris@16: using mapped_file::readwrite; Chris@16: using mapped_file::priv; Chris@16: using mapped_file::char_type; Chris@16: struct category Chris@16: : public sink_tag, Chris@16: public direct_tag, Chris@16: public closable_tag Chris@16: { }; Chris@16: using mapped_file::size_type; Chris@16: using mapped_file::iterator; Chris@16: using mapped_file::max_length; Chris@16: using mapped_file::is_open; Chris@16: using mapped_file::close; Chris@16: using mapped_file::operator safe_bool; Chris@16: using mapped_file::operator !; Chris@16: using mapped_file::flags; Chris@16: using mapped_file::size; Chris@16: using mapped_file::data; Chris@16: using mapped_file::begin; Chris@16: using mapped_file::end; Chris@16: using mapped_file::alignment; Chris@16: using mapped_file::resize; Chris@16: Chris@16: // Default constructor Chris@16: mapped_file_sink() { } Chris@16: Chris@16: // Constructor taking a parameters object Chris@16: template Chris@16: explicit mapped_file_sink(const basic_mapped_file_params& p); Chris@16: Chris@16: // Constructor taking a list of parameters Chris@16: template Chris@16: explicit mapped_file_sink( const Path& path, Chris@16: size_type length = max_length, Chris@16: boost::intmax_t offset = 0, Chris@16: mapmode flags = readwrite ); Chris@16: Chris@16: // Copy Constructor Chris@16: mapped_file_sink(const mapped_file_sink& other); Chris@16: Chris@16: // open overload taking a parameters object Chris@16: template Chris@16: void open(const basic_mapped_file_params& p); Chris@16: Chris@16: // open overload taking a list of parameters Chris@16: template Chris@16: void open( const Path& path, Chris@16: size_type length = max_length, Chris@16: boost::intmax_t offset = 0, Chris@16: mapmode flags = readwrite ); Chris@16: }; Chris@16: Chris@16: //------------------Implementation of mapped_file_source----------------------// Chris@16: Chris@16: template Chris@16: mapped_file_source::mapped_file_source(const basic_mapped_file_params& p) Chris@16: { init(); open(p); } Chris@16: Chris@16: template Chris@16: mapped_file_source::mapped_file_source( Chris@16: const Path& path, size_type length, boost::intmax_t offset) Chris@16: { init(); open(path, length, offset); } Chris@16: Chris@16: template Chris@16: void mapped_file_source::open(const basic_mapped_file_params& p) Chris@16: { Chris@16: param_type params(p); Chris@16: if (params.flags) { Chris@16: if (params.flags != mapped_file::readonly) Chris@16: boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags")); Chris@16: } else { Chris@16: if (params.mode & BOOST_IOS::out) Chris@16: boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); Chris@16: params.mode |= BOOST_IOS::in; Chris@16: } Chris@16: open_impl(params); Chris@16: } Chris@16: Chris@16: template Chris@16: void mapped_file_source::open( Chris@16: const Path& path, size_type length, boost::intmax_t offset) Chris@16: { Chris@16: param_type p(path); Chris@16: p.length = length; Chris@16: p.offset = offset; Chris@16: open(p); Chris@16: } Chris@16: Chris@16: //------------------Implementation of mapped_file-----------------------------// Chris@16: Chris@16: template Chris@16: mapped_file::mapped_file(const basic_mapped_file_params& p) Chris@16: { open(p); } Chris@16: Chris@16: template Chris@16: mapped_file::mapped_file( Chris@16: const Path& path, mapmode flags, Chris@16: size_type length, stream_offset offset ) Chris@16: { open(path, flags, length, offset); } Chris@16: Chris@16: template Chris@16: mapped_file::mapped_file( Chris@16: const Path& path, BOOST_IOS::openmode mode, Chris@16: size_type length, stream_offset offset ) Chris@16: { open(path, mode, length, offset); } Chris@16: Chris@16: template Chris@16: void mapped_file::open(const basic_mapped_file_params& p) Chris@16: { delegate_.open_impl(p); } Chris@16: Chris@16: template Chris@16: void mapped_file::open( Chris@16: const Path& path, mapmode flags, Chris@16: size_type length, stream_offset offset ) Chris@16: { Chris@16: param_type p(path); Chris@16: p.flags = flags; Chris@16: p.length = length; Chris@16: p.offset = offset; Chris@16: open(p); Chris@16: } Chris@16: Chris@16: template Chris@16: void mapped_file::open( Chris@16: const Path& path, BOOST_IOS::openmode mode, Chris@16: size_type length, stream_offset offset ) Chris@16: { Chris@16: param_type p(path); Chris@16: p.mode = mode; Chris@16: p.length = length; Chris@16: p.offset = offset; Chris@16: open(p); Chris@16: } Chris@16: Chris@16: inline char* mapped_file::data() const Chris@16: { return (flags() != readonly) ? const_cast(delegate_.data()) : 0; } Chris@16: Chris@16: //------------------Implementation of mapped_file_sink------------------------// Chris@16: Chris@16: template Chris@16: mapped_file_sink::mapped_file_sink(const basic_mapped_file_params& p) Chris@16: { open(p); } Chris@16: Chris@16: template Chris@16: mapped_file_sink::mapped_file_sink( Chris@16: const Path& path, size_type length, Chris@16: boost::intmax_t offset, mapmode flags ) Chris@16: { open(path, length, offset, flags); } Chris@16: Chris@16: template Chris@16: void mapped_file_sink::open(const basic_mapped_file_params& p) Chris@16: { Chris@16: param_type params(p); Chris@16: if (params.flags) { Chris@16: if (params.flags & mapped_file::readonly) Chris@16: boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags")); Chris@16: } else { Chris@16: if (params.mode & BOOST_IOS::in) Chris@16: boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode")); Chris@16: params.mode |= BOOST_IOS::out; Chris@16: } Chris@16: mapped_file::open(params); Chris@16: } Chris@16: Chris@16: template Chris@16: void mapped_file_sink::open( Chris@16: const Path& path, size_type length, Chris@16: boost::intmax_t offset, mapmode flags ) Chris@16: { Chris@16: param_type p(path); Chris@16: p.flags = flags; Chris@16: p.length = length; Chris@16: p.offset = offset; Chris@16: open(p); Chris@16: } Chris@16: Chris@16: //------------------Specialization of direct_impl-----------------------------// Chris@16: Chris@16: template<> Chris@16: struct operations Chris@16: : boost::iostreams::detail::close_impl Chris@16: { Chris@16: static std::pair Chris@16: input_sequence(mapped_file_source& src) Chris@16: { Chris@16: return std::make_pair( const_cast(src.begin()), Chris@16: const_cast(src.end()) ); Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct operations Chris@16: : boost::iostreams::detail::close_impl Chris@16: { Chris@16: static std::pair Chris@16: input_sequence(mapped_file& file) Chris@16: { Chris@16: return std::make_pair(file.begin(), file.end()); Chris@16: } Chris@16: static std::pair Chris@16: output_sequence(mapped_file& file) Chris@16: { Chris@16: return std::make_pair(file.begin(), file.end()); Chris@16: } Chris@16: }; Chris@16: Chris@16: template<> Chris@16: struct operations Chris@16: : boost::iostreams::detail::close_impl Chris@16: { Chris@16: static std::pair Chris@16: output_sequence(mapped_file_sink& sink) Chris@16: { Chris@16: return std::make_pair(sink.begin(), sink.end()); Chris@16: } Chris@16: }; Chris@16: Chris@16: //------------------Definition of mapmode operators---------------------------// Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator|(mapped_file::mapmode a, mapped_file::mapmode b) Chris@16: { Chris@16: return static_cast Chris@16: (static_cast(a) | static_cast(b)); Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator&(mapped_file::mapmode a, mapped_file::mapmode b) Chris@16: { Chris@16: return static_cast Chris@16: (static_cast(a) & static_cast(b)); Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator^(mapped_file::mapmode a, mapped_file::mapmode b) Chris@16: { Chris@16: return static_cast Chris@16: (static_cast(a) ^ static_cast(b)); Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator~(mapped_file::mapmode a) Chris@16: { Chris@16: return static_cast(~static_cast(a)); Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator|=(mapped_file::mapmode& a, mapped_file::mapmode b) Chris@16: { Chris@16: return a = a | b; Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator&=(mapped_file::mapmode& a, mapped_file::mapmode b) Chris@16: { Chris@16: return a = a & b; Chris@16: } Chris@16: Chris@16: inline mapped_file::mapmode Chris@16: operator^=(mapped_file::mapmode& a, mapped_file::mapmode b) Chris@16: { Chris@16: return a = a ^ b; Chris@16: } Chris@16: Chris@16: } } // End namespaces iostreams, boost. Chris@16: Chris@16: #include // pops abi_suffix.hpp pragmas Chris@16: Chris@16: #endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED