Boost logo

Boost-Commit :

Subject: [Boost-commit] svn:boost r73025 - sandbox/gil/boost/gil/extension/io2/detail
From: dsaritz_at_[hidden]
Date: 2011-07-12 19:18:25


Author: psiha
Date: 2011-07-12 19:18:24 EDT (Tue, 12 Jul 2011)
New Revision: 73025
URL: http://svn.boost.org/trac/boost/changeset/73025

Log:
Major refactoring of the memory mapping functionality:
 - replaced the memory_mapping and memory_mapping_source classes with the mapped_view class templates (and appropriate specialization) and the guard::mapped_view class template
 - changed lifetime management: using factory functions and an explicit guard class for mapped views
 - added the is_mappable metafunction.

Fixed the file_flags::create() member function.
Minor other refactoring and stylistic changes.
Text files modified:
   sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.cpp | 125 ++++++++++++--------
   sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.hpp | 234 ++++++++++++++++++++++++++++++++-------
   2 files changed, 264 insertions(+), 95 deletions(-)

Modified: sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.cpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.cpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.cpp 2011-07-12 19:18:24 EDT (Tue, 12 Jul 2011)
@@ -3,7 +3,7 @@
 /// \file memory_mapping.cpp
 /// ------------------------
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -100,8 +100,11 @@
     return handle_;
 }
 
+//------------------------------------------------------------------------------
+} // guard
 
-native_handle_guard create_file( char const * const file_name, file_flags const & flags )
+
+guard::native_handle create_file( char const * const file_name, file_flags const & flags )
 {
     BOOST_ASSERT( file_name );
 
@@ -124,12 +127,9 @@
 
 #endif // _WIN32
 
- return native_handle_guard( file_handle );
+ return guard::native_handle( file_handle );
 }
 
-//------------------------------------------------------------------------------
-} // guard
-
 
 bool set_file_size( guard::native_handle_t const file_handle, unsigned int const desired_size )
 {
@@ -201,20 +201,20 @@
         share_mode, // share_mode
         open_flags, // creation_disposition
         system_hints
- ||
+ |
         (
             ( on_construction_rights & FILE_ATTRIBUTE_NORMAL )
                 ? ( on_construction_rights & ~FILE_ATTRIBUTE_READONLY )
                 : on_construction_rights
         ) // flags_and_attributes
- #else
+ #else // POSIX
         ( ( handle_access_flags == O_RDONLY | O_WRONLY ) ? O_RDWR : handle_access_flags )
- ||
+ |
         open_flags
- ||
- system_hints,
- on_construction_rights
- #endif // _WIN32
+ |
+ system_hints, // oflag
+ on_construction_rights // pmode
+ #endif // OS impl
     };
 
     return flags;
@@ -223,7 +223,16 @@
 
 file_flags file_flags::create_for_opening_existing_files( unsigned int const handle_access_flags, unsigned int const share_mode , bool const truncate, unsigned int const system_hints )
 {
- return create( handle_access_flags, share_mode, truncate ? open_and_truncate_existing : open_existing, system_hints, 0 );
+ return create
+ (
+ handle_access_flags,
+ share_mode,
+ truncate
+ ? open_policy::open_and_truncate_existing
+ : open_policy::open_existing,
+ system_hints,
+ 0
+ );
 }
 
 
@@ -278,13 +287,17 @@
 }
 
 
-memory_mapping::memory_mapping
+template <>
+mapped_view<unsigned char> mapped_view<unsigned char>::map
 (
     guard::native_handle_t const object_handle,
     mapping_flags const & flags,
- std::size_t const desired_size
+ std::size_t const desired_size,
+ std::size_t const offset
 )
 {
+ typedef mapped_view<unsigned char>::iterator iterator_t;
+
 #ifdef _WIN32
 
     // Implementation note:
@@ -293,78 +306,82 @@
     // http://msdn.microsoft.com/en-us/library/aa366537(VS.85).aspx
     // (26.03.2010.) (Domagoj Saric)
 
+ ULARGE_INTEGER large_integer;
+
     // CreateFileMapping accepts INVALID_HANDLE_VALUE as valid input but only if
     // the size parameter is not null.
+ large_integer.QuadPart = desired_size;
     guard::windows_handle const mapping
     (
- ::CreateFileMapping( object_handle, 0, flags.create_mapping_flags, 0, desired_size, 0 )
+ ::CreateFileMapping( object_handle, 0, flags.create_mapping_flags, large_integer.HighPart, large_integer.LowPart, 0 )
     );
     BOOST_ASSERT
     (
         !mapping.handle() || ( object_handle == INVALID_HANDLE_VALUE ) || ( desired_size != 0 )
     );
 
- BOOST_ASSERT( this->empty() );
-
- iterator const view_start( static_cast<iterator>( ::MapViewOfFile( mapping.handle(), flags.map_view_flags, 0, 0, desired_size ) ) );
- iterator const view_end
+ large_integer.QuadPart = offset;
+ iterator_t const view_start( static_cast<iterator_t>( ::MapViewOfFile( mapping.handle(), flags.map_view_flags, large_integer.HighPart, large_integer.LowPart, desired_size ) ) );
+ return mapped_view<unsigned char>
     (
+ view_start,
         ( view_start && ( object_handle != INVALID_HANDLE_VALUE ) )
             ? view_start + desired_size
             : view_start
     );
 
-#else
+#else // POSIX
 
- iterator const view_start( desired_size ? static_cast<iterator>( ::mmap( 0, desired_size, flags.protection, flags.flags, file_handle, 0 ) ) : 0 );
- iterator const view_end
+ iterator_t const view_start( static_cast<iterator_t>( ::mmap( 0, desired_size, flags.protection, flags.flags, file_handle, 0 ) ) );
+ return mapped_view<unsigned char>
     (
+ view_start,
         ( view_start != MAP_FAILED )
             ? view_start + desired_size
             : view_start
     );
 
-#endif // _WIN32
-
- /// \todo Convert these constructors to factory functions to avoid the
- /// anti-pattern of a fallible-yet-nonthrowing constructor.
- /// (10.10.2010.) (Domagoj Saric)
- iterator_range::operator = ( iterator_range( view_start, view_end ) );
+#endif // OS API
 }
 
-
-memory_mapping::~memory_mapping()
+template <>
+void detail::mapped_view_base<unsigned char const>::unmap( detail::mapped_view_base<unsigned char const> const & mapped_range )
 {
 #ifdef _WIN32
- BOOST_VERIFY( ::UnmapViewOfFile( begin() ) || this->empty() );
+ BOOST_VERIFY( ::UnmapViewOfFile( mapped_range.begin() ) || mapped_range.empty() );
 #else
- BOOST_VERIFY( ( ::munmap( begin(), size() ) == 0 ) || this->empty() );
+ BOOST_VERIFY( ( ::munmap( mapped_range.begin(), mapped_range.size() ) == 0 ) || mapped_range.empty() );
 #endif // _WIN32
 }
 
-
-memory_mapped_source::memory_mapped_source( guard::native_handle_t const object_handle, unsigned int const desiredSize )
- :
- memory_mapping
+template <>
+mapped_view<unsigned char const> mapped_view<unsigned char const>::map
+(
+ guard::native_handle_t const object_handle,
+ std::size_t const desired_size,
+ std::size_t const offset,
+ bool const map_for_code_execution,
+ unsigned int const mapping_system_hints
+)
+{
+ return mapped_view<unsigned char>::map
     (
         object_handle,
         mapping_flags::create
         (
- mapping_flags::handle_access_rights::read,
- mapping_flags::share_mode ::shared,
- mapping_flags::system_hint ::uninitialized
+ mapping_flags::handle_access_rights::read | ( map_for_code_execution ? mapping_flags::handle_access_rights::execute : 0 ),
+ mapping_flags::share_mode::shared,
+ mapping_system_hints
         ),
- desiredSize
- )
-{
+ desired_size,
+ offset
+ );
 }
 
 
-memory_mapped_source map_read_only_file( char const * const file_name )
+mapped_view<unsigned char const> map_read_only_file( char const * const file_name )
 {
- using namespace guard;
-
- native_handle_guard const file_handle
+ guard::native_handle const file_handle
     (
         create_file
         (
@@ -372,14 +389,22 @@
             file_flags::create_for_opening_existing_files
             (
                 file_flags::handle_access_rights::read,
- file_flags::share_mode ::read,
+ file_flags::share_mode ::read | file_flags::share_mode::write,
                 false,
                 file_flags::system_hints ::sequential_access
             )
         )
     );
 
- return memory_mapped_source( file_handle.handle(), get_file_size( file_handle.handle() ) );
+ return mapped_view<unsigned char const>::map
+ (
+ file_handle.handle(),
+ #ifdef _WIN32
+ 0 // Windows APIs interpret zero as 'whole file'
+ #else // POSIX
+ get_file_size( file_handle.handle() )
+ #endif // OS impl
+ );
 }
 
 

Modified: sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.hpp
==============================================================================
--- sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.hpp (original)
+++ sandbox/gil/boost/gil/extension/io2/detail/memory_mapping.hpp 2011-07-12 19:18:24 EDT (Tue, 12 Jul 2011)
@@ -3,7 +3,7 @@
 /// \file memory_mapping.hpp
 /// ------------------------
 ///
-/// Copyright (c) Domagoj Saric 2010.
+/// Copyright (c) Domagoj Saric 2010.-2011.
 ///
 /// Use, modification and distribution is subject to the Boost Software License, Version 1.0.
 /// (See accompanying file LICENSE_1_0.txt or copy at
@@ -157,6 +157,13 @@
 #endif // _WIN32
 };
 
+
+typedef iterator_range<unsigned char *> basic_memory_range_t;
+typedef iterator_range<unsigned char const *> basic_read_only_memory_range_t;
+
+template <typename Element>
+class mapped_view;
+
 namespace guard
 {
 //------------------------------------------------------------------------------
@@ -198,82 +205,219 @@
 
 
 #ifdef _WIN32
- typedef windows_handle native_handle_guard;
+ typedef windows_handle native_handle;
 #else
- typedef posix_handle native_handle_guard;
+ typedef posix_handle native_handle;
 #endif // _WIN32
-typedef native_handle_guard::handle_t native_handle_t;
+typedef native_handle::handle_t native_handle_t;
 
 
-native_handle_guard create_file( char const * file_name, file_flags const & );
-native_handle_guard create_file( char const * file_name, file_flags const &, unsigned int desired_size );
+template <typename Element>
+class mapped_view : public boost::mapped_view<Element>
+{
+public:
+ mapped_view( boost::mapped_view<Element> const range ) : boost::mapped_view<Element>( range ) {}
+ ~mapped_view<Element>() { boost::mapped_view<Element>::unmap( *this ); }
+};
 
 //------------------------------------------------------------------------------
 } // namespace guard
 
+guard::native_handle create_file( char const * file_name, file_flags const & );
+guard::native_handle create_file( char const * file_name, file_flags const &, unsigned int desired_size );
+
 bool set_file_size( guard::native_handle_t, std::size_t desired_size );
 std::size_t get_file_size( guard::native_handle_t );
 
 
-typedef iterator_range<unsigned char const *> memory_chunk_t;//...zzz...this implicitly constructs from a string literal...
-typedef iterator_range<unsigned char *> writable_memory_chunk_t;
+namespace detail
+{
+ template <typename Element>
+ class mapped_view_base : public iterator_range<Element *>
+ {
+ public:
+ typedef iterator_range<Element> memory_range_t;
 
+ public: // Factory methods.
+ static void unmap( mapped_view_base const & );
 
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class memory_mapping
-///
-////////////////////////////////////////////////////////////////////////////////
+ protected:
+ mapped_view_base( iterator_range<Element *> const & mapped_range ) : iterator_range<Element *>( mapped_range ) {}
+ mapped_view_base( Element * const p_begin, Element * const p_end ) : iterator_range<Element *>( p_begin, p_end ) {}
+
+ static mapped_view<unsigned char const>
+ #ifdef BOOST_MSVC
+ const &
+ #endif
+ make_basic_view( mapped_view_base<Element> const & );
+
+ static mapped_view<Element>
+ #ifdef BOOST_MSVC
+ const &
+ #endif
+ make_typed_range( mapped_view_base<unsigned char const> const & );
+
+ private: // Hide mutable members
+ iterator_range & advance_begin( difference_type );
+ iterator_range & advance_end ( difference_type );
 
-class memory_mapping
- :
- private writable_memory_chunk_t
- #ifndef __GNUC__
- ,private boost::noncopyable
- #endif // __GNUC__
+ void pop_front();
+ void pop_back ();
+ };
+
+
+ template <typename Element>
+ void mapped_view_base<Element>::unmap( mapped_view_base<Element> const & mapped_range )
+ {
+ unmap<unsigned char const>( make_basic_view( mapped_range ) );
+ }
+
+ template <>
+ void mapped_view_base<unsigned char const>::unmap( mapped_view_base<unsigned char const> const & );
+
+ template <typename Element>
+ mapped_view<unsigned char const>
+ #ifdef BOOST_MSVC
+ const &
+ #endif
+ mapped_view_base<Element>::make_basic_view( mapped_view_base<Element> const & range )
+ {
+ return
+ #ifdef BOOST_MSVC
+ reinterpret_cast<mapped_view<unsigned char const> const &>( range );
+ #else // compiler might care about strict aliasing rules
+ mapped_view<unsigned char const>
+ (
+ static_cast<unsigned char const *>( static_cast<void const *>( range.begin() ) ),
+ static_cast<unsigned char const *>( static_cast<void const *>( range.end () ) )
+ );
+ #endif // compiler
+ }
+
+
+ template <typename Element>
+ mapped_view<Element>
+ #ifdef BOOST_MSVC
+ const &
+ #endif
+ mapped_view_base<Element>::make_typed_range( mapped_view_base<unsigned char const> const & range )
+ {
+ BOOST_ASSERT( range.begin() % sizeof( Element ) == 0 );
+ BOOST_ASSERT( range.end () % sizeof( Element ) == 0 );
+ BOOST_ASSERT( range.size () % sizeof( Element ) == 0 );
+ return
+ #ifdef BOOST_MSVC
+ reinterpret_cast<mapped_view<Element> const &>( range );
+ #else // compiler might care about strict aliasing rules
+ mapped_view<unsigned char const>
+ (
+ static_cast<Element *>( static_cast<void *>( range.begin() ) ),
+ static_cast<Element *>( static_cast<void *>( range.end () ) )
+ );
+ #endif // compiler
+ }
+} // namespace detail
+
+template <typename Element>
+class mapped_view : public detail::mapped_view_base<Element>
 {
 public:
- memory_mapping
+ basic_memory_range_t basic_range() const
+ {
+ return basic_memory_range_t
+ (
+ static_cast<unsigned char *>( static_cast<void *>( begin() ) ),
+ static_cast<unsigned char *>( static_cast<void *>( end () ) )
+ );
+ }
+
+public: // Factory methods.
+ static mapped_view map
     (
         guard::native_handle_t,
         mapping_flags const &,
- unsigned int desired_size
+ std::size_t desired_size,
+ std::size_t offset
     );
- ~memory_mapping();
-
- operator writable_memory_chunk_t const & () const { return memory_range(); }
 
-protected:
- writable_memory_chunk_t const & memory_range() const { return *this; }
+private:
+ mapped_view( iterator_range<Element *> const & mapped_range ) : mapped_view_base( mapped_range ) {}
+ mapped_view( Element * const p_begin, Element * const p_end ) : mapped_view_base( p_begin, p_end ) {}
 };
 
-
-////////////////////////////////////////////////////////////////////////////////
-///
-/// \class memory_mapped_source
-///
-////////////////////////////////////////////////////////////////////////////////
-
-class memory_mapped_source : private memory_mapping
+template <typename Element>
+class mapped_view<Element const> : public detail::mapped_view_base<Element const>
 {
 public:
- memory_mapped_source( guard::native_handle_t, unsigned int desired_size );
-
- operator memory_chunk_t const & () const
+ basic_memory_range_t basic_range() const
     {
- //writable_memory_chunk_t const & writable( *this );
- writable_memory_chunk_t const & writable( memory_mapping::memory_range() );
- memory_chunk_t const & readonly( reinterpret_cast<memory_chunk_t const &>( writable ) );
- BOOST_ASSERT( readonly == writable );
- return readonly;
+ return basic_memory_range_t
+ (
+ static_cast<unsigned char const *>( static_cast<void const *>( begin() ) ),
+ static_cast<unsigned char const *>( static_cast<void const *>( end () ) )
+ );
     }
 
-protected:
- memory_chunk_t const & memory_range() const { return *this; }
+public: // Factory methods.
+ static mapped_view map
+ (
+ guard::native_handle_t object_handle,
+ std::size_t desired_size,
+ std::size_t offset = 0,
+ bool map_for_code_execution = false,
+ unsigned int mapping_system_hints = mapping_flags::system_hint::uninitialized
+ );
+
+private:
+ mapped_view( iterator_range<Element const *> const & mapped_range ) : mapped_view_base( mapped_range ) {}
+ mapped_view( Element const * const p_begin, Element const * const p_end ) : mapped_view_base( p_begin, p_end ) {}
 };
 
+template <typename Handle>
+struct is_mappable : mpl::false_ {};
+
+template <> struct is_mappable<char *> : mpl::true_ {};
+template <> struct is_mappable<char const *> : mpl::true_ {};
+template <> struct is_mappable<FILE *> : mpl::true_ {};
+template <> struct is_mappable<guard::posix_handle::handle_t > : mpl::true_ {};
+#ifdef _WIN32
+template <> struct is_mappable<wchar_t *> : mpl::true_ {};
+template <> struct is_mappable<wchar_t const *> : mpl::true_ {};
+template <> struct is_mappable<guard::windows_handle::handle_t > : mpl::true_ {};
+#endif // _WIN32
+
+
+template <typename Element>
+mapped_view<Element> mapped_view<Element>::map
+(
+ guard::native_handle_t,
+ mapping_flags const &,
+ std::size_t desired_size,
+ std::size_t offset
+);
+
+
+template <>
+mapped_view<unsigned char> mapped_view<unsigned char>::map
+(
+ guard::native_handle_t,
+ mapping_flags const &,
+ std::size_t desired_size,
+ std::size_t offset
+);
+
+template <>
+mapped_view<unsigned char const> mapped_view<unsigned char const>::map
+(
+ guard::native_handle_t object_handle,
+ std::size_t desired_size,
+ std::size_t offset,
+ bool map_for_code_execution,
+ unsigned int mapping_system_hints
+);
+
 
-memory_mapped_source map_read_only_file( char const * file_name );
+mapped_view<unsigned char const> map_read_only_file( char const * file_name );
 
 //------------------------------------------------------------------------------
 } // namespace boost


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