$include_dir="/home/hyper-archives/boost-commit/include"; include("$include_dir/msg-header.inc") ?>
From: technews_at_[hidden]
Date: 2008-06-25 14:23:59
Author: turkanis
Date: 2008-06-25 14:23:59 EDT (Wed, 25 Jun 2008)
New Revision: 46692
URL: http://svn.boost.org/trac/boost/changeset/46692
Log:
applied changes from Jorge Lodos (with modifications)
Text files modified: 
   trunk/boost/iostreams/device/mapped_file.hpp   |   575 ++++++++++++++++++++++++-------         
   trunk/libs/iostreams/src/mapped_file.cpp       |   722 +++++++++++++++++++++------------------ 
   trunk/libs/iostreams/test/mapped_file_test.cpp |   188 +++++++--                               
   3 files changed, 982 insertions(+), 503 deletions(-)
Modified: trunk/boost/iostreams/device/mapped_file.hpp
==============================================================================
--- trunk/boost/iostreams/device/mapped_file.hpp	(original)
+++ trunk/boost/iostreams/device/mapped_file.hpp	2008-06-25 14:23:59 EDT (Wed, 25 Jun 2008)
@@ -1,41 +1,16 @@
-// (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
 
 #include <boost/config.hpp>                   // make sure size_t is in std.
 #include <cstddef>                            // size_t.
+#include <ctime>                              // size_t.
 #include <string>                             // pathnames.
 #include <utility>                            // pair.
 #include <boost/config.hpp>                   // BOOST_MSVC.
@@ -44,90 +19,178 @@
 #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/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 
+    BOOST_STATIC_ASSERT((!is_same<Path, std::wstring>::value));
+
+    // 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 impl_type;
+    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---------------------------------------//
 
@@ -136,114 +199,328 @@
     iterator begin() const;
     iterator end() const;
 
+    //--------------File access and modification times------------------------//
+
+    std::time_t last_read_time() const;
+    void set_last_read_time(std::time_t) const;
+    std::time_t last_write_time() const;
+    void set_last_write_time(std::time_t) const;
+
     //--------------Query admissible offsets----------------------------------//
 
     // Returns the allocation granularity for virtual memory. Values passed
     // as offsets must be multiples of this value.
     static int alignment();
+
 private:
-    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);
+    std::time_t last_read_time() const;
+    void set_last_read_time(std::time_t) const;
+    std::time_t last_write_time() const;
+    void set_last_write_time(std::time_t) const;
+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;
+    using mapped_file::last_read_time;
+    using mapped_file::set_last_read_time;
+    using mapped_file::last_write_time;
+    using mapped_file::set_last_write_time;
+
+    // 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 +528,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
Modified: trunk/libs/iostreams/src/mapped_file.cpp
==============================================================================
--- trunk/libs/iostreams/src/mapped_file.cpp	(original)
+++ trunk/libs/iostreams/src/mapped_file.cpp	2008-06-25 14:23:59 EDT (Wed, 25 Jun 2008)
@@ -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,17 @@
 #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/file_times.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
+# include <time.h>
 #else
 # include <errno.h>
 # include <fcntl.h>
@@ -38,423 +29,494 @@
 # 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);
+    std::time_t last_read_time() const;
+    void set_last_read_time(std::time_t) const;
+    std::time_t last_write_time() const;
+    void set_last_write_time(std::time_t) const;
+    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_source::mapped_file_source(mapped_file_params p) { open(p); }
-
-mapped_file_source::mapped_file_source( const std::string& path,
-                                        mapped_file_source::size_type length,
-                                        boost::intmax_t offset )
-{ open(path, length, offset); }
+mapped_file_impl::mapped_file_impl() { clear(false); }
 
-void mapped_file_source::open(mapped_file_params p)
-{
-    p.mode &= ~BOOST_IOS::out;
-    open_impl(p);
-}
+mapped_file_impl::~mapped_file_impl() 
+{ try { close(); } catch (...) { } }
 
-void mapped_file_source::open( const std::string& path,
-                               mapped_file_source::size_type length,
-                               boost::intmax_t offset )
+void mapped_file_impl::open(param_type p)
 {
-    mapped_file_params p(path);
-    p.mode = BOOST_IOS::in;
-    p.length = length;
-    p.offset = offset;
-    open_impl(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
-{
-    return !!pimpl_ && pimpl_->error_ == false ?
-        &safe_bool_helper::x : 0;
+    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;
 }
 
-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_; }
+std::time_t mapped_file_impl::last_read_time() const
+{ return detail::last_read_time(handle_); }
 
-const char* mapped_file_source::begin() const { return data(); }
+void mapped_file_impl::set_last_read_time(std::time_t tm) const
+{ detail::set_last_read_time(handle_, tm); }
 
-const char* mapped_file_source::end() const { return data() + size(); }
+std::time_t mapped_file_impl::last_write_time() const
+{ return detail::last_write_time(handle_); }
 
-#ifdef BOOST_IOSTREAMS_WINDOWS //---------------------------------------------//
+void mapped_file_impl::set_last_write_time(std::time_t tm) const
+{ detail::set_last_write_time(handle_, tm); }
 
-namespace detail {
-
-void cleanup_and_throw(detail::mapped_file_impl& impl, std::string msg)
+int mapped_file_impl::alignment()
 {
-    #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.to_wstring().c_str(),
+            dwDesiredAccess,
+            FILE_SHARE_READ,
+            NULL,
+            dwCreationDisposition,
+            dwFlagsandAttributes,
+            NULL ) :
+        ::CreateFileA( 
+            p.path.to_string().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");
-        }
+        ::SetFilePointer(handle_, sizelow, &sizehigh, FILE_BEGIN);
+        if (::GetLastError() != NO_ERROR || !::SetEndOfFile(handle_))
+            cleanup_and_throw("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");
-    }
-
-    //--------------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
+
+    // Open file
+    int flags = (readonly ? O_RDONLY : O_RDWR);
+    if (p.new_file_size != 0 && !readonly)
+        flags |= (O_CREAT | O_TRUNC);
+    #ifdef _LARGEFILE64_SOURCE
+        oflag |= O_LARGEFILE;
+    #endif
+    errno = 0;
+    handle_ = ::open(p.path.to_string().c_str(), flags, S_IRWXU);
+    if (errno != 0)
+        cleanup_and_throw("failed opening file");
+
+    //--------------Set file size---------------------------------------------//
+
+    if (p.new_file_size != 0 && !readonly)
+        if (BOOST_IOSTREAMS_FD_TRUNCATE(handle_, p.new_file_size) == -1)
+            cleanup_and_throw("failed setting file size");
+
+    //--------------Determine file size---------------------------------------//
+
+    bool success = true;
+    if (p.length != max_length) {
+        size_ = p.length;
+    } else {
+        struct BOOST_IOSTREAMS_FD_STAT info;
+        success = ::BOOST_IOSTREAMS_FD_FSTAT(handle_, &info) != -1;
+        size_ = info.st_size;
+    }
+    if (!success)
+        cleanup_and_throw("failed querying file size");
+#endif // #ifdef BOOST_IOSTREAMS_WINDOWS
+}
 
-    pimpl_->data_ = reinterpret_cast<char*>(data);
+void mapped_file_impl::try_map_file(param_type p)
+{
+	bool priv = p.flags == mapped_file::priv;
+    bool readonly = p.flags == mapped_file::readonly;
+#ifdef BOOST_IOSTREAMS_WINDOWS
+
+    // Create mapping
+	DWORD protect = priv ? 
+        PAGE_WRITECOPY : 
+        readonly ? 
+            PAGE_READONLY : 
+            PAGE_READWRITE;
+    mapped_handle_ = 
+        ::CreateFileMappingA( 
+            handle_, 
+            NULL,
+            protect,
+            0, 
+            0, 
+            NULL );
+    if (mapped_handle_ == NULL)
+        cleanup_and_throw("failed create mapping");
+
+    // Access data
+    DWORD access = priv ? 
+        FILE_MAP_COPY : 
+        readonly ? 
+            FILE_MAP_READ : 
+            FILE_MAP_WRITE;
+    void* data =
+        ::MapViewOfFileEx( 
+            mapped_handle_,
+            access,
+            (DWORD) (params_.offset >> 32),
+            (DWORD) (params_.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( 
+            p.hint_, 
+            size_,
+            readonly ? PROT_READ : (PROT_READ | PROT_WRITE),
+            priv ? MAP_PRIVATE : MAP_SHARED,
+            handle_, 
+            params_.offset );
+    if (data == MAP_FAILED)
+        cleanup_and_throw("failed mapping file");
+#endif
+    data_ = static_cast<char*>(data);
 }
 
-bool mapped_file_source::is_open() const
-{ return !!pimpl_ && pimpl_->handle_ != INVALID_HANDLE_VALUE; }
+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;
+        }
+    }
+}
 
-int mapped_file_source::alignment()
+bool mapped_file_impl::unmap_file()
 {
-    SYSTEM_INFO info;
-    ::GetSystemInfo(&info);
-    return static_cast<int>(info.dwAllocationGranularity);
+#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
 }
 
-#else // #ifdef BOOST_IOSTREAMS_WINDOWS //------------------------------------//
+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;
+}
 
-namespace detail {
+// 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);
+}
 
-    void cleanup_and_throw(detail::mapped_file_impl& impl, std::string msg)
+//------------------Implementation of mapped_file_params_base-----------------//
+
+void mapped_file_params_base::normalize()
 {
-    #ifndef NDEBUG
-        msg += std::string(" (\"") + impl.path_ + "\")";
-    #endif
-    if (impl.handle_ != 0)
-        ::close(impl.handle_);
-    impl.clear(true);
-    throw_system_failure(msg);
+    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----------------------//
 
-void mapped_file_source::open_impl(mapped_file_params p)
-{
-    using namespace std;
+mapped_file_source::mapped_file_source() 
+    : pimpl_(new impl_type)
+    { }
+
+mapped_file_source::mapped_file_source(const mapped_file_source& other)
+    : pimpl_(other.pimpl_)
+    { }
 
-    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
+bool mapped_file_source::is_open() const
+{ return pimpl_->is_open(); }
 
-    //--------------Open underlying file--------------------------------------//
+void mapped_file_source::close() { pimpl_->close(); }
 
-    int flags = (readonly ? O_RDONLY : O_RDWR);
-    if (p.new_file_size != 0 && !readonly)
-        flags |= (O_CREAT | O_TRUNC);
-    errno = 0;
-    pimpl_->handle_ = ::open(p.path.c_str(), flags, S_IRWXU);
-    if (errno != 0)
-        detail::cleanup_and_throw(*pimpl_, "failed opening file");
+mapped_file_source::operator safe_bool() const
+{ return pimpl_->error() ? &safe_bool_helper::x : 0; }
 
-    //--------------Set file size---------------------------------------------//
+bool mapped_file_source::operator!() const
+{ return pimpl_->error(); }
 
-    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");
+mapped_file_source::mapmode mapped_file_source::flags() const 
+{ return pimpl_->flags(); }
 
-    //--------------Determine file size---------------------------------------//
+mapped_file_source::size_type mapped_file_source::size() const
+{ return pimpl_->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 (!success)
-        detail::cleanup_and_throw(*pimpl_, "failed getting file size");
+const char* mapped_file_source::data() const { return pimpl_->data(); }
+
+const char* mapped_file_source::begin() const { return data(); }
 
-    //--------------Create mapping--------------------------------------------//
+const char* mapped_file_source::end() const { return data() + size(); }
 
-    try_again: // Target of goto in following section.
+std::time_t mapped_file_source::last_read_time() const
+{ return pimpl_->last_read_time(); }
 
-    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;
-        }
-        detail::cleanup_and_throw(*pimpl_, "failed mapping file");
-    }
-    pimpl_->data_ = reinterpret_cast<char*>(data);
+void mapped_file_source::set_last_read_time(std::time_t tm) const
+{ pimpl_->set_last_read_time(tm); }
 
-    return;
-}
+std::time_t mapped_file_source::last_write_time() const
+{ return pimpl_->last_write_time(); }
 
-bool mapped_file_source::is_open() const
-{ return !!pimpl_ && pimpl_->handle_ != 0; }
+void mapped_file_source::set_last_write_time(std::time_t tm) const
+{ pimpl_->set_last_write_time(tm); }
 
 int mapped_file_source::alignment()
-{ return static_cast<int>(sysconf(_SC_PAGESIZE)); }
+{ return detail::mapped_file_impl::alignment(); }
 
-#endif // #ifdef BOOST_IOSTREAMS_WINDOWS //-----------------------------------//
+void mapped_file_source::init() { pimpl_.reset(new impl_type); }
+
+void mapped_file_source::open_impl(const param_type& p)
+{ pimpl_->open(p); }
 
 //------------------Implementation of mapped_file-----------------------------//
 
-mapped_file::mapped_file(mapped_file_params p) { delegate_.open_impl(p); }
+mapped_file::mapped_file(const mapped_file& other)
+    : delegate_(other.delegate_)
+    { }
 
-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);
-}
+void mapped_file::resize(stream_offset new_size)
+{ delegate_.pimpl_->resize(new_size); }
 
-//------------------Implementation of mapped_file_sink------------------------//
+std::time_t mapped_file::last_read_time() const
+{ return delegate_.pimpl_->last_read_time(); }
 
-mapped_file_sink::mapped_file_sink(mapped_file_params p) { open(p); }
+void mapped_file::set_last_read_time(std::time_t tm) const
+{ delegate_.pimpl_->set_last_read_time(tm); }
 
-mapped_file_sink::mapped_file_sink( const std::string& path,
-                                    size_type length, stream_offset offset )
-{ open(path, length, offset); }
+std::time_t mapped_file::last_write_time() const
+{ return delegate_.pimpl_->last_write_time(); }
 
-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::set_last_write_time(std::time_t tm) const
+{ delegate_.pimpl_->set_last_write_time(tm); }
 
-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);
-}
+//------------------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: trunk/libs/iostreams/test/mapped_file_test.cpp
==============================================================================
--- trunk/libs/iostreams/test/mapped_file_test.cpp	(original)
+++ trunk/libs/iostreams/test/mapped_file_test.cpp	2008-06-25 14:23:59 EDT (Wed, 25 Jun 2008)
@@ -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"
             );
 
@@ -56,12 +93,12 @@
 
         // Test reading from a stream based on a mapped_file_source,
         // in chunks. (Also tests reopening the stream.)
-        first.open(mapped_file_source(test1.name()));
+		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;
-        out.open(mapped_file_sink(first.name()));
-        write_data_in_chars(out);
+		boost::iostreams::stream<mapped_file_sink> out;
+		out.open(mapped_file_sink(first.name()));
+        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"
         );
 
@@ -94,11 +131,11 @@
 
         // 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);
+		out.open(mapped_file_sink(second.name()));
+        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;
-        out.open(mapped_file_sink(p));
-        write_data_in_chars(out);
+		mapped_file_params p(first.name());
+        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));
+        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"
         );
 
@@ -129,11 +166,11 @@
         // Test writing to a newly created mapped file. 
         // (Also tests reopening the stream.)
         p.path = second.name();
-        out.open(mapped_file_sink(p));
-        write_data_in_chunks(out);
+		out.open(mapped_file_sink(p));
+        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;
-        io.open(mapped_file(test.name()));
+        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"
         );
 
@@ -160,9 +197,9 @@
         // Test reading, writing and seeking within a stream based on a 
         // mapped_file, in chunks. (Also tests reopening the 
         // stream.)
-        io.open(mapped_file(test.name()));
+		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;
 }