| 1 | // (C) Copyright Jonathan Turkanis 2003. | 
|---|
| 2 | // (C) Copyright Craig Henderson 2002.   'boost/memmap.hpp' from sandbox | 
|---|
| 3 | // Distributed under the Boost Software License, Version 1.0. (See accompanying | 
|---|
| 4 | // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.) | 
|---|
| 5 |  | 
|---|
| 6 | // See http://www.boost.org/libs/iostreams for documentation. | 
|---|
| 7 |  | 
|---|
| 8 | // | 
|---|
| 9 | // This header and its accompanying source file libs/iostreams/memmap.cpp are | 
|---|
| 10 | // an adaptation of Craig Henderson's memmory mapped file library. The | 
|---|
| 11 | // interface has been revised significantly, but the underlying OS-specific | 
|---|
| 12 | // code is essentially the same, with some code from Boost.Filesystem | 
|---|
| 13 | // mixed in. (See notations in source.) | 
|---|
| 14 | // | 
|---|
| 15 | // The following changes have been made: | 
|---|
| 16 | // | 
|---|
| 17 | // 1. OS-specific code put in a .cpp file. | 
|---|
| 18 | // 2. Name of main class changed to mapped_file. | 
|---|
| 19 | // 3. mapped_file given an interface similar to std::fstream (open(), | 
|---|
| 20 | //    is_open(), close()) and std::string (data(), size(), begin(), end()). | 
|---|
| 21 | // 4. An additional class readonly_mapped_file has been provided as a | 
|---|
| 22 | //    convenience. | 
|---|
| 23 | // 5. [Obsolete: Error states are reported using filesystem::error_code.] | 
|---|
| 24 | // 6. Read-only or read-write states are specified using ios_base::openmode. | 
|---|
| 25 | // 7. Access to the underlying file handles and to security parameters | 
|---|
| 26 | //    has been removed. | 
|---|
| 27 | // | 
|---|
| 28 |  | 
|---|
| 29 | #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED | 
|---|
| 30 | #define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED | 
|---|
| 31 |  | 
|---|
| 32 | #if defined(_MSC_VER) && (_MSC_VER >= 1020) | 
|---|
| 33 | # pragma once | 
|---|
| 34 | #endif | 
|---|
| 35 |  | 
|---|
| 36 | #include <boost/config.hpp>                   // make sure size_t is in std. | 
|---|
| 37 | #include <cstddef>                            // size_t. | 
|---|
| 38 | #include <string>                             // pathnames. | 
|---|
| 39 | #include <utility>                            // pair. | 
|---|
| 40 | #include <boost/config.hpp>                   // BOOST_MSVC. | 
|---|
| 41 | #include <boost/detail/workaround.hpp> | 
|---|
| 42 | #include <boost/iostreams/close.hpp> | 
|---|
| 43 | #include <boost/iostreams/concepts.hpp> | 
|---|
| 44 | #include <boost/iostreams/detail/config/auto_link.hpp> | 
|---|
| 45 | #include <boost/iostreams/detail/config/dyn_link.hpp> | 
|---|
| 46 | #include <boost/iostreams/detail/ios.hpp>     // openmode. | 
|---|
| 47 | #include <boost/iostreams/operations_fwd.hpp> | 
|---|
| 48 | #include <boost/iostreams/positioning.hpp> | 
|---|
| 49 | #include <boost/shared_ptr.hpp> | 
|---|
| 50 |  | 
|---|
| 51 | // Must come last. | 
|---|
| 52 | #include <boost/iostreams/detail/config/disable_warnings.hpp> | 
|---|
| 53 | #include <boost/config/abi_prefix.hpp> | 
|---|
| 54 |  | 
|---|
| 55 | namespace boost { namespace iostreams { | 
|---|
| 56 |  | 
|---|
| 57 | namespace detail { | 
|---|
| 58 |  | 
|---|
| 59 | struct mapped_file_impl; | 
|---|
| 60 |  | 
|---|
| 61 | } // End namespace detail. | 
|---|
| 62 |  | 
|---|
| 63 | struct mapped_file_params { | 
|---|
| 64 |     explicit mapped_file_params() | 
|---|
| 65 |         : mode(), offset(0), length(static_cast<std::size_t>(-1)), | 
|---|
| 66 |           new_file_size(0), hint(0) | 
|---|
| 67 |         { } | 
|---|
| 68 |     explicit mapped_file_params(const std::string& path) | 
|---|
| 69 |         : path(path), mode(), offset(0), | 
|---|
| 70 |           length(static_cast<std::size_t>(-1)), | 
|---|
| 71 |           new_file_size(0), hint(0) | 
|---|
| 72 |         { } | 
|---|
| 73 |     std::string          path; | 
|---|
| 74 |     BOOST_IOS::openmode  mode; | 
|---|
| 75 |     stream_offset        offset; | 
|---|
| 76 |     std::size_t          length; | 
|---|
| 77 |     stream_offset        new_file_size; | 
|---|
| 78 |     const char*          hint; | 
|---|
| 79 | }; | 
|---|
| 80 |  | 
|---|
| 81 | //------------------Definition of mapped_file_source--------------------------// | 
|---|
| 82 |  | 
|---|
| 83 | class BOOST_IOSTREAMS_DECL mapped_file_source { | 
|---|
| 84 | private: | 
|---|
| 85 |     struct safe_bool_helper { int x; };         // From Bronek Kozicki. | 
|---|
| 86 |     typedef int safe_bool_helper::* safe_bool; | 
|---|
| 87 |     friend struct operations<mapped_file_source>; | 
|---|
| 88 | public: | 
|---|
| 89 |     typedef char               char_type; | 
|---|
| 90 |     struct category | 
|---|
| 91 |         : public source_tag, | 
|---|
| 92 |           public direct_tag, | 
|---|
| 93 |           public closable_tag | 
|---|
| 94 |         { }; | 
|---|
| 95 |     typedef std::size_t        size_type; | 
|---|
| 96 |     typedef const char*        iterator; | 
|---|
| 97 |     BOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1)); | 
|---|
| 98 |  | 
|---|
| 99 |     mapped_file_source() { } | 
|---|
| 100 |     explicit mapped_file_source(mapped_file_params); | 
|---|
| 101 |     explicit mapped_file_source( const std::string& path, | 
|---|
| 102 |                                  size_type length = max_length, | 
|---|
| 103 |                                  boost::intmax_t offset = 0 ); | 
|---|
| 104 |  | 
|---|
| 105 |     //--------------Stream interface------------------------------------------// | 
|---|
| 106 |  | 
|---|
| 107 |     void open(mapped_file_params params); | 
|---|
| 108 |     void open( const std::string& path, | 
|---|
| 109 |                size_type length = max_length, | 
|---|
| 110 |                boost::intmax_t offset = 0 ); | 
|---|
| 111 |     bool is_open() const; | 
|---|
| 112 |     void close(); | 
|---|
| 113 |  | 
|---|
| 114 |     operator safe_bool() const; | 
|---|
| 115 |     bool operator!() const; | 
|---|
| 116 |     BOOST_IOS::openmode mode() const; | 
|---|
| 117 |  | 
|---|
| 118 |     //--------------Container interface---------------------------------------// | 
|---|
| 119 |  | 
|---|
| 120 |     size_type size() const; | 
|---|
| 121 |     const char* data() const; | 
|---|
| 122 |     iterator begin() const; | 
|---|
| 123 |     iterator end() const; | 
|---|
| 124 |  | 
|---|
| 125 |     //--------------Query admissible offsets----------------------------------// | 
|---|
| 126 |  | 
|---|
| 127 |     // Returns the allocation granularity for virtual memory. Values passed | 
|---|
| 128 |     // as offsets must be multiples of this value. | 
|---|
| 129 |     static int alignment(); | 
|---|
| 130 | private: | 
|---|
| 131 |     friend class mapped_file; | 
|---|
| 132 |     typedef detail::mapped_file_impl impl_type; | 
|---|
| 133 |     void open_impl(mapped_file_params); | 
|---|
| 134 |  | 
|---|
| 135 |     boost::shared_ptr<impl_type> pimpl_; | 
|---|
| 136 | }; | 
|---|
| 137 |  | 
|---|
| 138 | //------------------Definition of mapped_file---------------------------------// | 
|---|
| 139 |  | 
|---|
| 140 | class BOOST_IOSTREAMS_DECL mapped_file { | 
|---|
| 141 | private: | 
|---|
| 142 |     typedef mapped_file_source delegate_type; | 
|---|
| 143 |     delegate_type delegate_; | 
|---|
| 144 |     friend struct operations<mapped_file>; | 
|---|
| 145 | public: | 
|---|
| 146 |     typedef char                           char_type; | 
|---|
| 147 |     struct category | 
|---|
| 148 |         : public seekable_device_tag, | 
|---|
| 149 |           public direct_tag, | 
|---|
| 150 |           public closable_tag | 
|---|
| 151 |         { }; | 
|---|
| 152 |     typedef mapped_file_source::size_type  size_type; | 
|---|
| 153 |     typedef char*                          iterator; | 
|---|
| 154 |     typedef const char*                    const_iterator; | 
|---|
| 155 |     BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length); | 
|---|
| 156 |     mapped_file() { } | 
|---|
| 157 |     explicit mapped_file(mapped_file_params p); | 
|---|
| 158 |     explicit mapped_file( const std::string& path, | 
|---|
| 159 |                           BOOST_IOS::openmode mode = | 
|---|
| 160 |                               BOOST_IOS::in | BOOST_IOS::out, | 
|---|
| 161 |                           size_type length = max_length, | 
|---|
| 162 |                           stream_offset offset = 0 ); | 
|---|
| 163 |  | 
|---|
| 164 |     //--------------Conversion to readonly_mapped_file------------------------// | 
|---|
| 165 |  | 
|---|
| 166 |     operator mapped_file_source&() { return delegate_; } | 
|---|
| 167 |     operator const mapped_file_source&() const { return delegate_; } | 
|---|
| 168 |  | 
|---|
| 169 |     //--------------Stream interface------------------------------------------// | 
|---|
| 170 |  | 
|---|
| 171 |     void open(mapped_file_params p); | 
|---|
| 172 |     void open( const std::string& path, | 
|---|
| 173 |                BOOST_IOS::openmode mode = | 
|---|
| 174 |                    BOOST_IOS::in | BOOST_IOS::out, | 
|---|
| 175 |                size_type length = max_length, | 
|---|
| 176 |                stream_offset offset = 0 ); | 
|---|
| 177 |     bool is_open() const { return delegate_.is_open(); } | 
|---|
| 178 |     void close() { delegate_.close(); } | 
|---|
| 179 |     operator delegate_type::safe_bool() const { return delegate_; } | 
|---|
| 180 |     bool operator!() const { return !is_open(); } | 
|---|
| 181 |     BOOST_IOS::openmode mode() const { return delegate_.mode(); } | 
|---|
| 182 |  | 
|---|
| 183 |     //--------------Container interface---------------------------------------// | 
|---|
| 184 |  | 
|---|
| 185 |     size_type size() const { return delegate_.size(); } | 
|---|
| 186 |     char* data() const  | 
|---|
| 187 |     {  | 
|---|
| 188 |         return (mode() & BOOST_IOS::out) ? | 
|---|
| 189 |             const_cast<char*>(delegate_.data()) : | 
|---|
| 190 |             0; | 
|---|
| 191 |     } | 
|---|
| 192 |     const char* const_data() const { return delegate_.data(); } | 
|---|
| 193 |     iterator begin() const { return data(); } | 
|---|
| 194 |     const_iterator const_begin() const { return data(); } | 
|---|
| 195 |     iterator end() const { return data() + size(); } | 
|---|
| 196 |     const_iterator const_end() const { return data() + size(); } | 
|---|
| 197 |  | 
|---|
| 198 |     //--------------Query admissible offsets----------------------------------// | 
|---|
| 199 |  | 
|---|
| 200 |     // Returns the allocation granularity for virtual memory. Values passed | 
|---|
| 201 |     // as offsets must be multiples of this value. | 
|---|
| 202 |     static int alignment() { return mapped_file_source::alignment(); } | 
|---|
| 203 | }; | 
|---|
| 204 |  | 
|---|
| 205 | struct BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file { | 
|---|
| 206 |     friend struct operations<mapped_file_sink>; | 
|---|
| 207 |     typedef char char_type; | 
|---|
| 208 |     struct category | 
|---|
| 209 |         : public sink_tag, | 
|---|
| 210 |           public direct_tag, | 
|---|
| 211 |           public closable_tag | 
|---|
| 212 |         { }; | 
|---|
| 213 |     using mapped_file::close; | 
|---|
| 214 |     explicit mapped_file_sink(mapped_file_params p); | 
|---|
| 215 |     explicit mapped_file_sink( const std::string& path, | 
|---|
| 216 |                                size_type length = max_length, | 
|---|
| 217 |                                boost::intmax_t offset = 0 ); | 
|---|
| 218 |     void open(mapped_file_params p); | 
|---|
| 219 |     void open( const std::string& path, | 
|---|
| 220 |                size_type length = max_length, | 
|---|
| 221 |                boost::intmax_t offset = 0 ); | 
|---|
| 222 | }; | 
|---|
| 223 |  | 
|---|
| 224 | //------------------Specialization of direct_impl-----------------------------// | 
|---|
| 225 |  | 
|---|
| 226 | template<> | 
|---|
| 227 | struct operations<boost::iostreams::mapped_file_source> | 
|---|
| 228 |     : detail::close_impl<closable_tag> | 
|---|
| 229 | { | 
|---|
| 230 |     static std::pair<char*, char*> | 
|---|
| 231 |     input_sequence(boost::iostreams::mapped_file_source& src) | 
|---|
| 232 |     { | 
|---|
| 233 |         return std::make_pair( const_cast<char*>(src.begin()), | 
|---|
| 234 |                                const_cast<char*>(src.end()) ); | 
|---|
| 235 |     } | 
|---|
| 236 | }; | 
|---|
| 237 |  | 
|---|
| 238 | template<> | 
|---|
| 239 | struct operations<boost::iostreams::mapped_file_sink> | 
|---|
| 240 |     : detail::close_impl<closable_tag> | 
|---|
| 241 | { | 
|---|
| 242 |     static std::pair<char*, char*> | 
|---|
| 243 |     output_sequence(boost::iostreams::mapped_file_sink& sink) | 
|---|
| 244 |     {  | 
|---|
| 245 |         return std::make_pair(sink.begin(), sink.end());  | 
|---|
| 246 |     } | 
|---|
| 247 | }; | 
|---|
| 248 |  | 
|---|
| 249 | template<> | 
|---|
| 250 | struct operations<boost::iostreams::mapped_file> | 
|---|
| 251 |     : detail::close_impl<closable_tag> | 
|---|
| 252 | { | 
|---|
| 253 |     static std::pair<char*, char*> | 
|---|
| 254 |     input_sequence(boost::iostreams::mapped_file& file) | 
|---|
| 255 |     {  | 
|---|
| 256 |         return std::make_pair(file.begin(), file.end());  | 
|---|
| 257 |     } | 
|---|
| 258 |     static std::pair<char*, char*> | 
|---|
| 259 |     output_sequence(boost::iostreams::mapped_file& file) | 
|---|
| 260 |     {  | 
|---|
| 261 |         return std::make_pair(file.begin(), file.end());  | 
|---|
| 262 |     } | 
|---|
| 263 | }; | 
|---|
| 264 |  | 
|---|
| 265 | } } // End namespaces iostreams, boost. | 
|---|
| 266 |  | 
|---|
| 267 | #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas | 
|---|
| 268 | #include <boost/iostreams/detail/config/enable_warnings.hpp> // MSVC. | 
|---|
| 269 |  | 
|---|
| 270 | #endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED | 
|---|