1 // (C) Copyright Jorge Lodos 2008.
2 // (C) Copyright Jonathan Turkanis 2003.
3 // (C) Copyright Craig Henderson 2002. 'boost/memmap.hpp' from sandbox
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt.)
7 #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
8 #define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
14 #include <boost/config.hpp> // make sure size_t is in std.
15 #include <cstddef> // size_t.
16 #include <string> // pathnames.
17 #include <utility> // pair.
18 #include <boost/config.hpp> // BOOST_MSVC.
19 #include <boost/detail/workaround.hpp>
20 #include <boost/iostreams/close.hpp>
21 #include <boost/iostreams/concepts.hpp>
22 #include <boost/iostreams/detail/config/auto_link.hpp>
23 #include <boost/iostreams/detail/config/dyn_link.hpp>
24 #include <boost/iostreams/detail/config/wide_streams.hpp>
25 #include <boost/iostreams/detail/ios.hpp> // openmode, failure
26 #include <boost/iostreams/detail/path.hpp>
27 #include <boost/iostreams/operations_fwd.hpp>
28 #include <boost/iostreams/positioning.hpp>
29 #include <boost/shared_ptr.hpp>
30 #include <boost/static_assert.hpp>
31 #include <boost/throw_exception.hpp>
32 #include <boost/type_traits/is_same.hpp>
35 #if defined(BOOST_MSVC)
36 # pragma warning(push)
37 # pragma warning(disable:4251) // Missing DLL interface for shared_ptr
39 #include <boost/config/abi_prefix.hpp>
41 namespace boost { namespace iostreams {
43 //------------------Definition of mapped_file_base and mapped_file_params-----//
45 // Forward declarations
46 class mapped_file_source;
47 class mapped_file_sink;
49 namespace detail { class mapped_file_impl; }
51 class mapped_file_base {
60 // Bitmask operations for mapped_file_base::mapmode
61 mapped_file_base::mapmode
62 operator|(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
64 mapped_file_base::mapmode
65 operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
67 mapped_file_base::mapmode
68 operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
70 mapped_file_base::mapmode
71 operator~(mapped_file_base::mapmode a);
73 mapped_file_base::mapmode
74 operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
76 mapped_file_base::mapmode
77 operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
79 mapped_file_base::mapmode
80 operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
82 //------------------Definition of mapped_file_params--------------------------//
86 struct mapped_file_params_base {
87 mapped_file_params_base()
88 : flags(static_cast<mapped_file_base::mapmode>(0)),
89 mode(), offset(0), length(static_cast<std::size_t>(-1)),
90 new_file_size(0), hint(0)
93 friend class mapped_file_impl;
96 mapped_file_base::mapmode flags;
97 BOOST_IOS::openmode mode; // Deprecated
100 stream_offset new_file_size;
104 } // End namespace detail.
106 // This template allows Boost.Filesystem paths to be specified when creating or
107 // reopening a memory mapped file, without creating a dependence on
108 // Boost.Filesystem. Possible values of Path include std::string,
109 // boost::filesystem::path, boost::filesystem::wpath,
110 // and boost::iostreams::detail::path (used to store either a std::string or a
112 template<typename Path>
113 struct basic_mapped_file_params
114 : detail::mapped_file_params_base
116 typedef detail::mapped_file_params_base base_type;
118 // For wide paths, instantiate basic_mapped_file_params
119 // with boost::filesystem::wpath
120 #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
121 BOOST_STATIC_ASSERT((!is_same<Path, std::wstring>::value));
124 // Default constructor
125 basic_mapped_file_params() { }
127 // Construction from a Path
128 explicit basic_mapped_file_params(const Path& p) : path(p) { }
130 // Construction from a path of a different type
131 template<typename PathT>
132 explicit basic_mapped_file_params(const PathT& p) : path(p) { }
135 basic_mapped_file_params(const basic_mapped_file_params& other)
136 : base_type(other), path(other.path)
139 // Templated copy constructor
140 template<typename PathT>
141 basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
142 : base_type(other), path(other.path)
145 typedef Path path_type;
149 typedef basic_mapped_file_params<std::string> mapped_file_params;
151 //------------------Definition of mapped_file_source--------------------------//
153 class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base {
155 struct safe_bool_helper { int x; };
156 typedef int safe_bool_helper::* safe_bool;
157 typedef detail::mapped_file_impl impl_type;
158 typedef basic_mapped_file_params<detail::path> param_type;
159 friend class mapped_file;
160 friend class detail::mapped_file_impl;
161 friend struct boost::iostreams::operations<mapped_file_source>;
163 typedef char char_type;
169 typedef std::size_t size_type;
170 typedef const char* iterator;
171 BOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1));
173 // Default constructor
174 mapped_file_source();
176 // Constructor taking a parameters object
177 template<typename Path>
178 explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
180 // Constructor taking a list of parameters
181 template<typename Path>
182 explicit mapped_file_source( const Path& path,
183 size_type length = max_length,
184 boost::intmax_t offset = 0 );
187 mapped_file_source(const mapped_file_source& other);
189 //--------------Stream interface------------------------------------------//
191 template<typename Path>
192 void open(const basic_mapped_file_params<Path>& p);
194 template<typename Path>
195 void open( const Path& path,
196 size_type length = max_length,
197 boost::intmax_t offset = 0 );
199 bool is_open() const;
201 operator safe_bool() const;
202 bool operator!() const;
203 mapmode flags() const;
205 //--------------Container interface---------------------------------------//
207 size_type size() const;
208 const char* data() const;
209 iterator begin() const;
210 iterator end() const;
212 //--------------Query admissible offsets----------------------------------//
214 // Returns the allocation granularity for virtual memory. Values passed
215 // as offsets must be multiples of this value.
216 static int alignment();
220 void open_impl(const param_type& p);
222 boost::shared_ptr<impl_type> pimpl_;
225 //------------------Definition of mapped_file---------------------------------//
227 class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base {
229 typedef mapped_file_source delegate_type;
230 typedef delegate_type::safe_bool safe_bool;
231 typedef basic_mapped_file_params<detail::path> param_type;
232 friend struct boost::iostreams::operations<mapped_file >;
233 friend class mapped_file_sink;
235 typedef char char_type;
237 : public seekable_device_tag,
241 typedef mapped_file_source::size_type size_type;
242 typedef char* iterator;
243 typedef const char* const_iterator;
244 BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length);
246 // Default constructor
249 // Construstor taking a parameters object
250 template<typename Path>
251 explicit mapped_file(const basic_mapped_file_params<Path>& p);
253 // Constructor taking a list of parameters
254 template<typename Path>
255 mapped_file( const Path& path,
257 size_type length = max_length,
258 stream_offset offset = 0 );
260 // Constructor taking a list of parameters, including a
261 // std::ios_base::openmode (deprecated)
262 template<typename Path>
263 explicit mapped_file( const Path& path,
264 BOOST_IOS::openmode mode =
265 BOOST_IOS::in | BOOST_IOS::out,
266 size_type length = max_length,
267 stream_offset offset = 0 );
270 mapped_file(const mapped_file& other);
272 //--------------Conversion to mapped_file_source (deprecated)-------------//
274 operator mapped_file_source&() { return delegate_; }
275 operator const mapped_file_source&() const { return delegate_; }
277 //--------------Stream interface------------------------------------------//
279 // open overload taking a parameters object
280 template<typename Path>
281 void open(const basic_mapped_file_params<Path>& p);
283 // open overload taking a list of parameters
284 template<typename Path>
285 void open( const Path& path,
287 size_type length = max_length,
288 stream_offset offset = 0 );
290 // open overload taking a list of parameters, including a
291 // std::ios_base::openmode (deprecated)
292 template<typename Path>
293 void open( const Path& path,
294 BOOST_IOS::openmode mode =
295 BOOST_IOS::in | BOOST_IOS::out,
296 size_type length = max_length,
297 stream_offset offset = 0 );
299 bool is_open() const { return delegate_.is_open(); }
300 void close() { delegate_.close(); }
301 operator safe_bool() const { return delegate_; }
302 bool operator!() const { return !delegate_; }
303 mapmode flags() const { return delegate_.flags(); }
305 //--------------Container interface---------------------------------------//
307 size_type size() const { return delegate_.size(); }
309 const char* const_data() const { return delegate_.data(); }
310 iterator begin() const { return data(); }
311 const_iterator const_begin() const { return const_data(); }
312 iterator end() const;
313 const_iterator const_end() const { return const_data() + size(); }
315 //--------------Query admissible offsets----------------------------------//
317 // Returns the allocation granularity for virtual memory. Values passed
318 // as offsets must be multiples of this value.
319 static int alignment() { return mapped_file_source::alignment(); }
321 //--------------File access----------------------------------------------//
323 void resize(stream_offset new_size);
325 delegate_type delegate_;
328 //------------------Definition of mapped_file_sink----------------------------//
330 class BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file {
332 friend struct boost::iostreams::operations<mapped_file_sink>;
333 using mapped_file::mapmode;
334 using mapped_file::readonly;
335 using mapped_file::readwrite;
336 using mapped_file::priv;
337 using mapped_file::char_type;
343 using mapped_file::size_type;
344 using mapped_file::iterator;
345 using mapped_file::max_length;
346 using mapped_file::is_open;
347 using mapped_file::close;
348 using mapped_file::operator safe_bool;
349 using mapped_file::operator !;
350 using mapped_file::flags;
351 using mapped_file::size;
352 using mapped_file::data;
353 using mapped_file::begin;
354 using mapped_file::end;
355 using mapped_file::alignment;
356 using mapped_file::resize;
358 // Default constructor
359 mapped_file_sink() { }
361 // Constructor taking a parameters object
362 template<typename Path>
363 explicit mapped_file_sink(const basic_mapped_file_params<Path>& p);
365 // Constructor taking a list of parameters
366 template<typename Path>
367 explicit mapped_file_sink( const Path& path,
368 size_type length = max_length,
369 boost::intmax_t offset = 0,
370 mapmode flags = readwrite );
373 mapped_file_sink(const mapped_file_sink& other);
375 // open overload taking a parameters object
376 template<typename Path>
377 void open(const basic_mapped_file_params<Path>& p);
379 // open overload taking a list of parameters
380 template<typename Path>
381 void open( const Path& path,
382 size_type length = max_length,
383 boost::intmax_t offset = 0,
384 mapmode flags = readwrite );
387 //------------------Implementation of mapped_file_source----------------------//
389 template<typename Path>
390 mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
393 template<typename Path>
394 mapped_file_source::mapped_file_source(
395 const Path& path, size_type length, boost::intmax_t offset)
396 { init(); open(path, length, offset); }
398 template<typename Path>
399 void mapped_file_source::open(const basic_mapped_file_params<Path>& p)
401 param_type params(p);
403 if (params.flags != mapped_file::readonly)
404 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
406 if (params.mode & BOOST_IOS::out)
407 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
408 params.mode |= BOOST_IOS::in;
413 template<typename Path>
414 void mapped_file_source::open(
415 const Path& path, size_type length, boost::intmax_t offset)
423 //------------------Implementation of mapped_file-----------------------------//
425 template<typename Path>
426 mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
429 template<typename Path>
430 mapped_file::mapped_file(
431 const Path& path, mapmode flags,
432 size_type length, stream_offset offset )
433 { open(path, flags, length, offset); }
435 template<typename Path>
436 mapped_file::mapped_file(
437 const Path& path, BOOST_IOS::openmode mode,
438 size_type length, stream_offset offset )
439 { open(path, mode, length, offset); }
441 template<typename Path>
442 void mapped_file::open(const basic_mapped_file_params<Path>& p)
443 { delegate_.open_impl(p); }
445 template<typename Path>
446 void mapped_file::open(
447 const Path& path, mapmode flags,
448 size_type length, stream_offset offset )
457 template<typename Path>
458 void mapped_file::open(
459 const Path& path, BOOST_IOS::openmode mode,
460 size_type length, stream_offset offset )
469 inline char* mapped_file::data() const
470 { return (flags() != readonly) ? const_cast<char*>(delegate_.data()) : 0; }
472 inline mapped_file::iterator mapped_file::end() const
473 { return (flags() != readonly) ? data() + size() : 0; }
475 //------------------Implementation of mapped_file_sink------------------------//
477 template<typename Path>
478 mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
481 template<typename Path>
482 mapped_file_sink::mapped_file_sink(
483 const Path& path, size_type length,
484 boost::intmax_t offset, mapmode flags )
485 { open(path, length, offset, flags); }
487 template<typename Path>
488 void mapped_file_sink::open(const basic_mapped_file_params<Path>& p)
490 param_type params(p);
492 if (params.flags & mapped_file::readonly)
493 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
495 if (params.mode & BOOST_IOS::in)
496 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
497 params.mode |= BOOST_IOS::out;
499 mapped_file::open(params);
502 template<typename Path>
503 void mapped_file_sink::open(
504 const Path& path, size_type length,
505 boost::intmax_t offset, mapmode flags )
514 //------------------Specialization of direct_impl-----------------------------//
517 struct operations<mapped_file_source>
518 : boost::iostreams::detail::close_impl<closable_tag>
520 static std::pair<char*, char*>
521 input_sequence(mapped_file_source& src)
523 return std::make_pair( const_cast<char*>(src.begin()),
524 const_cast<char*>(src.end()) );
529 struct operations<mapped_file>
530 : boost::iostreams::detail::close_impl<closable_tag>
532 static std::pair<char*, char*>
533 input_sequence(mapped_file& file)
535 return std::make_pair(file.begin(), file.end());
537 static std::pair<char*, char*>
538 output_sequence(mapped_file& file)
540 return std::make_pair(file.begin(), file.end());
545 struct operations<mapped_file_sink>
546 : boost::iostreams::detail::close_impl<closable_tag>
548 static std::pair<char*, char*>
549 output_sequence(mapped_file_sink& sink)
551 return std::make_pair(sink.begin(), sink.end());
555 //------------------Definition of mapmode operators---------------------------//
557 inline mapped_file::mapmode
558 operator|(mapped_file::mapmode a, mapped_file::mapmode b)
560 return static_cast<mapped_file::mapmode>
561 (static_cast<int>(a) | static_cast<int>(b));
564 inline mapped_file::mapmode
565 operator&(mapped_file::mapmode a, mapped_file::mapmode b)
567 return static_cast<mapped_file::mapmode>
568 (static_cast<int>(a) & static_cast<int>(b));
571 inline mapped_file::mapmode
572 operator^(mapped_file::mapmode a, mapped_file::mapmode b)
574 return static_cast<mapped_file::mapmode>
575 (static_cast<int>(a) ^ static_cast<int>(b));
578 inline mapped_file::mapmode
579 operator~(mapped_file::mapmode a)
581 return static_cast<mapped_file::mapmode>(~static_cast<int>(a));
584 inline mapped_file::mapmode
585 operator|=(mapped_file::mapmode& a, mapped_file::mapmode b)
590 inline mapped_file::mapmode
591 operator&=(mapped_file::mapmode& a, mapped_file::mapmode b)
596 inline mapped_file::mapmode
597 operator^=(mapped_file::mapmode& a, mapped_file::mapmode b)
602 } } // End namespaces iostreams, boost.
604 #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
605 #if defined(BOOST_MSVC)
606 # pragma warning(pop) // pops #pragma warning(disable:4251)
609 #endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED