Line data Source code
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.)
6 :
7 : #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
8 : #define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
9 :
10 : #if defined(_MSC_VER)
11 : # pragma once
12 : #endif
13 :
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>
33 :
34 : // Must come last.
35 : #if defined(BOOST_MSVC)
36 : # pragma warning(push)
37 : # pragma warning(disable:4251) // Missing DLL interface for shared_ptr
38 : #endif
39 : #include <boost/config/abi_prefix.hpp>
40 :
41 : namespace boost { namespace iostreams {
42 :
43 : //------------------Definition of mapped_file_base and mapped_file_params-----//
44 :
45 : // Forward declarations
46 : class mapped_file_source;
47 : class mapped_file_sink;
48 : class mapped_file;
49 : namespace detail { class mapped_file_impl; }
50 :
51 : class mapped_file_base {
52 : public:
53 : enum mapmode {
54 : readonly = 1,
55 : readwrite = 2,
56 : priv = 4
57 : };
58 : };
59 :
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);
63 :
64 : mapped_file_base::mapmode
65 : operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
66 :
67 : mapped_file_base::mapmode
68 : operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
69 :
70 : mapped_file_base::mapmode
71 : operator~(mapped_file_base::mapmode a);
72 :
73 : mapped_file_base::mapmode
74 : operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
75 :
76 : mapped_file_base::mapmode
77 : operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
78 :
79 : mapped_file_base::mapmode
80 : operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
81 :
82 : //------------------Definition of mapped_file_params--------------------------//
83 :
84 : namespace detail {
85 :
86 : struct mapped_file_params_base {
87 0 : mapped_file_params_base()
88 0 : : flags(static_cast<mapped_file_base::mapmode>(0)),
89 : mode(), offset(0), length(static_cast<std::size_t>(-1)),
90 0 : new_file_size(0), hint(0)
91 : { }
92 : private:
93 : friend class mapped_file_impl;
94 : void normalize();
95 : public:
96 : mapped_file_base::mapmode flags;
97 : BOOST_IOS::openmode mode; // Deprecated
98 : stream_offset offset;
99 : std::size_t length;
100 : stream_offset new_file_size;
101 : const char* hint;
102 : };
103 :
104 : } // End namespace detail.
105 :
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
111 : // std::wstring).
112 : template<typename Path>
113 0 : struct basic_mapped_file_params
114 : : detail::mapped_file_params_base
115 : {
116 : typedef detail::mapped_file_params_base base_type;
117 :
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));
122 : #endif
123 :
124 : // Default constructor
125 : basic_mapped_file_params() { }
126 :
127 : // Construction from a Path
128 0 : explicit basic_mapped_file_params(const Path& p) : path(p) { }
129 :
130 : // Construction from a path of a different type
131 : template<typename PathT>
132 : explicit basic_mapped_file_params(const PathT& p) : path(p) { }
133 :
134 : // Copy constructor
135 0 : basic_mapped_file_params(const basic_mapped_file_params& other)
136 0 : : base_type(other), path(other.path)
137 0 : { }
138 :
139 : // Templated copy constructor
140 : template<typename PathT>
141 0 : basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
142 0 : : base_type(other), path(other.path)
143 0 : { }
144 :
145 : typedef Path path_type;
146 : Path path;
147 : };
148 :
149 : typedef basic_mapped_file_params<std::string> mapped_file_params;
150 :
151 : //------------------Definition of mapped_file_source--------------------------//
152 :
153 0 : class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base {
154 : private:
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>;
162 : public:
163 : typedef char char_type;
164 : struct category
165 : : public source_tag,
166 : public direct_tag,
167 : public closable_tag
168 : { };
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));
172 :
173 : // Default constructor
174 : mapped_file_source();
175 :
176 : // Constructor taking a parameters object
177 : template<typename Path>
178 : explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
179 :
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 );
185 :
186 : // Copy Constructor
187 : mapped_file_source(const mapped_file_source& other);
188 :
189 : //--------------Stream interface------------------------------------------//
190 :
191 : template<typename Path>
192 : void open(const basic_mapped_file_params<Path>& p);
193 :
194 : template<typename Path>
195 : void open( const Path& path,
196 : size_type length = max_length,
197 : boost::intmax_t offset = 0 );
198 :
199 : bool is_open() const;
200 : void close();
201 : operator safe_bool() const;
202 : bool operator!() const;
203 : mapmode flags() const;
204 :
205 : //--------------Container interface---------------------------------------//
206 :
207 : size_type size() const;
208 : const char* data() const;
209 : iterator begin() const;
210 : iterator end() const;
211 :
212 : //--------------Query admissible offsets----------------------------------//
213 :
214 : // Returns the allocation granularity for virtual memory. Values passed
215 : // as offsets must be multiples of this value.
216 : static int alignment();
217 :
218 : private:
219 : void init();
220 : void open_impl(const param_type& p);
221 :
222 : boost::shared_ptr<impl_type> pimpl_;
223 : };
224 :
225 : //------------------Definition of mapped_file---------------------------------//
226 :
227 : class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base {
228 : private:
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;
234 : public:
235 : typedef char char_type;
236 : struct category
237 : : public seekable_device_tag,
238 : public direct_tag,
239 : public closable_tag
240 : { };
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);
245 :
246 : // Default constructor
247 : mapped_file() { }
248 :
249 : // Construstor taking a parameters object
250 : template<typename Path>
251 : explicit mapped_file(const basic_mapped_file_params<Path>& p);
252 :
253 : // Constructor taking a list of parameters
254 : template<typename Path>
255 : mapped_file( const Path& path,
256 : mapmode flags,
257 : size_type length = max_length,
258 : stream_offset offset = 0 );
259 :
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 );
268 :
269 : // Copy Constructor
270 : mapped_file(const mapped_file& other);
271 :
272 : //--------------Conversion to mapped_file_source (deprecated)-------------//
273 :
274 : operator mapped_file_source&() { return delegate_; }
275 : operator const mapped_file_source&() const { return delegate_; }
276 :
277 : //--------------Stream interface------------------------------------------//
278 :
279 : // open overload taking a parameters object
280 : template<typename Path>
281 : void open(const basic_mapped_file_params<Path>& p);
282 :
283 : // open overload taking a list of parameters
284 : template<typename Path>
285 : void open( const Path& path,
286 : mapmode mode,
287 : size_type length = max_length,
288 : stream_offset offset = 0 );
289 :
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 );
298 :
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 0 : mapmode flags() const { return delegate_.flags(); }
304 :
305 : //--------------Container interface---------------------------------------//
306 :
307 0 : size_type size() const { return delegate_.size(); }
308 : char* data() const;
309 0 : 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(); }
314 :
315 : //--------------Query admissible offsets----------------------------------//
316 :
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(); }
320 :
321 : //--------------File access----------------------------------------------//
322 :
323 : void resize(stream_offset new_size);
324 : private:
325 : delegate_type delegate_;
326 : };
327 :
328 : //------------------Definition of mapped_file_sink----------------------------//
329 :
330 : class BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file {
331 : public:
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;
338 : struct category
339 : : public sink_tag,
340 : public direct_tag,
341 : public closable_tag
342 : { };
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;
357 :
358 : // Default constructor
359 : mapped_file_sink() { }
360 :
361 : // Constructor taking a parameters object
362 : template<typename Path>
363 : explicit mapped_file_sink(const basic_mapped_file_params<Path>& p);
364 :
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 );
371 :
372 : // Copy Constructor
373 : mapped_file_sink(const mapped_file_sink& other);
374 :
375 : // open overload taking a parameters object
376 : template<typename Path>
377 : void open(const basic_mapped_file_params<Path>& p);
378 :
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 );
385 : };
386 :
387 : //------------------Implementation of mapped_file_source----------------------//
388 :
389 : template<typename Path>
390 : mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
391 : { init(); open(p); }
392 :
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); }
397 :
398 : template<typename Path>
399 : void mapped_file_source::open(const basic_mapped_file_params<Path>& p)
400 : {
401 : param_type params(p);
402 : if (params.flags) {
403 : if (params.flags != mapped_file::readonly)
404 : boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
405 : } else {
406 : if (params.mode & BOOST_IOS::out)
407 : boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
408 : params.mode |= BOOST_IOS::in;
409 : }
410 : open_impl(params);
411 : }
412 :
413 : template<typename Path>
414 : void mapped_file_source::open(
415 : const Path& path, size_type length, boost::intmax_t offset)
416 : {
417 : param_type p(path);
418 : p.length = length;
419 : p.offset = offset;
420 : open(p);
421 : }
422 :
423 : //------------------Implementation of mapped_file-----------------------------//
424 :
425 : template<typename Path>
426 0 : mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
427 0 : { open(p); }
428 :
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); }
434 :
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); }
440 :
441 : template<typename Path>
442 0 : void mapped_file::open(const basic_mapped_file_params<Path>& p)
443 0 : { delegate_.open_impl(p); }
444 :
445 : template<typename Path>
446 : void mapped_file::open(
447 : const Path& path, mapmode flags,
448 : size_type length, stream_offset offset )
449 : {
450 : param_type p(path);
451 : p.flags = flags;
452 : p.length = length;
453 : p.offset = offset;
454 : open(p);
455 : }
456 :
457 : template<typename Path>
458 : void mapped_file::open(
459 : const Path& path, BOOST_IOS::openmode mode,
460 : size_type length, stream_offset offset )
461 : {
462 : param_type p(path);
463 : p.mode = mode;
464 : p.length = length;
465 : p.offset = offset;
466 : open(p);
467 : }
468 :
469 0 : inline char* mapped_file::data() const
470 0 : { return (flags() != readonly) ? const_cast<char*>(delegate_.data()) : 0; }
471 :
472 : inline mapped_file::iterator mapped_file::end() const
473 : { return (flags() != readonly) ? data() + size() : 0; }
474 :
475 : //------------------Implementation of mapped_file_sink------------------------//
476 :
477 : template<typename Path>
478 : mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
479 : { open(p); }
480 :
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); }
486 :
487 : template<typename Path>
488 : void mapped_file_sink::open(const basic_mapped_file_params<Path>& p)
489 : {
490 : param_type params(p);
491 : if (params.flags) {
492 : if (params.flags & mapped_file::readonly)
493 : boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
494 : } else {
495 : if (params.mode & BOOST_IOS::in)
496 : boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
497 : params.mode |= BOOST_IOS::out;
498 : }
499 : mapped_file::open(params);
500 : }
501 :
502 : template<typename Path>
503 : void mapped_file_sink::open(
504 : const Path& path, size_type length,
505 : boost::intmax_t offset, mapmode flags )
506 : {
507 : param_type p(path);
508 : p.flags = flags;
509 : p.length = length;
510 : p.offset = offset;
511 : open(p);
512 : }
513 :
514 : //------------------Specialization of direct_impl-----------------------------//
515 :
516 : template<>
517 : struct operations<mapped_file_source>
518 : : boost::iostreams::detail::close_impl<closable_tag>
519 : {
520 : static std::pair<char*, char*>
521 : input_sequence(mapped_file_source& src)
522 : {
523 : return std::make_pair( const_cast<char*>(src.begin()),
524 : const_cast<char*>(src.end()) );
525 : }
526 : };
527 :
528 : template<>
529 : struct operations<mapped_file>
530 : : boost::iostreams::detail::close_impl<closable_tag>
531 : {
532 : static std::pair<char*, char*>
533 : input_sequence(mapped_file& file)
534 : {
535 : return std::make_pair(file.begin(), file.end());
536 : }
537 : static std::pair<char*, char*>
538 : output_sequence(mapped_file& file)
539 : {
540 : return std::make_pair(file.begin(), file.end());
541 : }
542 : };
543 :
544 : template<>
545 : struct operations<mapped_file_sink>
546 : : boost::iostreams::detail::close_impl<closable_tag>
547 : {
548 : static std::pair<char*, char*>
549 : output_sequence(mapped_file_sink& sink)
550 : {
551 : return std::make_pair(sink.begin(), sink.end());
552 : }
553 : };
554 :
555 : //------------------Definition of mapmode operators---------------------------//
556 :
557 : inline mapped_file::mapmode
558 : operator|(mapped_file::mapmode a, mapped_file::mapmode b)
559 : {
560 : return static_cast<mapped_file::mapmode>
561 : (static_cast<int>(a) | static_cast<int>(b));
562 : }
563 :
564 : inline mapped_file::mapmode
565 : operator&(mapped_file::mapmode a, mapped_file::mapmode b)
566 : {
567 : return static_cast<mapped_file::mapmode>
568 : (static_cast<int>(a) & static_cast<int>(b));
569 : }
570 :
571 : inline mapped_file::mapmode
572 : operator^(mapped_file::mapmode a, mapped_file::mapmode b)
573 : {
574 : return static_cast<mapped_file::mapmode>
575 : (static_cast<int>(a) ^ static_cast<int>(b));
576 : }
577 :
578 : inline mapped_file::mapmode
579 : operator~(mapped_file::mapmode a)
580 : {
581 : return static_cast<mapped_file::mapmode>(~static_cast<int>(a));
582 : }
583 :
584 : inline mapped_file::mapmode
585 : operator|=(mapped_file::mapmode& a, mapped_file::mapmode b)
586 : {
587 : return a = a | b;
588 : }
589 :
590 : inline mapped_file::mapmode
591 : operator&=(mapped_file::mapmode& a, mapped_file::mapmode b)
592 : {
593 : return a = a & b;
594 : }
595 :
596 : inline mapped_file::mapmode
597 : operator^=(mapped_file::mapmode& a, mapped_file::mapmode b)
598 : {
599 : return a = a ^ b;
600 : }
601 :
602 : } } // End namespaces iostreams, boost.
603 :
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)
607 : #endif
608 :
609 : #endif // #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
|