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 { mapped_file_paramsboost::iostreams::mapped_file_params64 explicit mapped_file_params() 65 : mode(), offset(0), length(static_cast<std::size_t>(-1)), 66 new_file_size(0), hint(0) 67 { } mapped_file_paramsboost::iostreams::mapped_file_params68 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 mapped_file_source()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); mapped_file()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 operator mapped_file_source&()166 operator mapped_file_source&() { return delegate_; } operator const mapped_file_source&() const167 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 ); is_open() const177 bool is_open() const { return delegate_.is_open(); } close()178 void close() { delegate_.close(); } operator delegate_type::safe_bool() const179 operator delegate_type::safe_bool() const { return delegate_; } operator !() const180 bool operator!() const { return !is_open(); } mode() const181 BOOST_IOS::openmode mode() const { return delegate_.mode(); } 182 183 //--------------Container interface---------------------------------------// 184 size() const185 size_type size() const { return delegate_.size(); } data() const186 char* data() const 187 { 188 return (mode() & BOOST_IOS::out) ? 189 const_cast<char*>(delegate_.data()) : 190 0; 191 } const_data() const192 const char* const_data() const { return delegate_.data(); } begin() const193 iterator begin() const { return data(); } const_begin() const194 const_iterator const_begin() const { return data(); } end() const195 iterator end() const { return data() + size(); } const_end() const196 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. alignment()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*> input_sequenceboost::iostreams::operations231 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*> output_sequenceboost::iostreams::operations243 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*> input_sequenceboost::iostreams::operations254 input_sequence(boost::iostreams::mapped_file& file) 255 { 256 return std::make_pair(file.begin(), file.end()); 257 } 258 static std::pair<char*, char*> output_sequenceboost::iostreams::operations259 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 271