• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
mapped_file_params_baseboost::iostreams::detail::mapped_file_params_base87     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)
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 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
basic_mapped_file_paramsboost::iostreams::basic_mapped_file_params125     basic_mapped_file_params() { }
126 
127     // Construction from a Path
basic_mapped_file_paramsboost::iostreams::basic_mapped_file_params128     explicit basic_mapped_file_params(const Path& p) : path(p) { }
129 
130     // Construction from a path of a different type
131     template<typename PathT>
basic_mapped_file_paramsboost::iostreams::basic_mapped_file_params132     explicit basic_mapped_file_params(const PathT& p) : path(p) { }
133 
134     // Copy constructor
basic_mapped_file_paramsboost::iostreams::basic_mapped_file_params135     basic_mapped_file_params(const basic_mapped_file_params& other)
136         : base_type(other), path(other.path)
137         { }
138 
139     // Templated copy constructor
140     template<typename PathT>
basic_mapped_file_paramsboost::iostreams::basic_mapped_file_params141     basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
142         : base_type(other), path(other.path)
143         { }
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 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
mapped_file()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 
operator mapped_file_source&()274     operator mapped_file_source&() { return delegate_; }
operator const mapped_file_source&() const275     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 
is_open() const299     bool is_open() const { return delegate_.is_open(); }
close()300     void close() { delegate_.close(); }
operator safe_bool() const301     operator safe_bool() const { return delegate_; }
operator !() const302     bool operator!() const { return !delegate_; }
flags() const303     mapmode flags() const { return delegate_.flags(); }
304 
305     //--------------Container interface---------------------------------------//
306 
size() const307     size_type size() const { return delegate_.size(); }
308     char* data() const;
const_data() const309     const char* const_data() const { return delegate_.data(); }
begin() const310     iterator begin() const { return data(); }
const_begin() const311     const_iterator const_begin() const { return const_data(); }
312     iterator end() const;
const_end() const313     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.
alignment()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
mapped_file_sink()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>
mapped_file_source(const basic_mapped_file_params<Path> & p)390 mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
391 { init(); open(p); }
392 
393 template<typename Path>
mapped_file_source(const Path & path,size_type length,boost::intmax_t offset)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>
open(const basic_mapped_file_params<Path> & p)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>
open(const Path & path,size_type length,boost::intmax_t offset)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>
mapped_file(const basic_mapped_file_params<Path> & p)426 mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
427 { open(p); }
428 
429 template<typename Path>
mapped_file(const Path & path,mapmode flags,size_type length,stream_offset offset)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>
mapped_file(const Path & path,BOOST_IOS::openmode mode,size_type length,stream_offset offset)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>
open(const basic_mapped_file_params<Path> & p)442 void mapped_file::open(const basic_mapped_file_params<Path>& p)
443 { delegate_.open_impl(p); }
444 
445 template<typename Path>
open(const Path & path,mapmode flags,size_type length,stream_offset offset)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>
open(const Path & path,BOOST_IOS::openmode mode,size_type length,stream_offset offset)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 
data() const469 inline char* mapped_file::data() const
470 { return (flags() != readonly) ? const_cast<char*>(delegate_.data()) : 0; }
471 
end() const472 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>
mapped_file_sink(const basic_mapped_file_params<Path> & p)478 mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
479 { open(p); }
480 
481 template<typename Path>
mapped_file_sink(const Path & path,size_type length,boost::intmax_t offset,mapmode flags)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>
open(const basic_mapped_file_params<Path> & p)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>
open(const Path & path,size_type length,boost::intmax_t offset,mapmode flags)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*>
input_sequenceboost::iostreams::operations521     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*>
input_sequenceboost::iostreams::operations533     input_sequence(mapped_file& file)
534     {
535         return std::make_pair(file.begin(), file.end());
536     }
537     static std::pair<char*, char*>
output_sequenceboost::iostreams::operations538     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*>
output_sequenceboost::iostreams::operations549     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
operator |(mapped_file::mapmode a,mapped_file::mapmode b)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
operator &(mapped_file::mapmode a,mapped_file::mapmode b)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
operator ^(mapped_file::mapmode a,mapped_file::mapmode b)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
operator ~(mapped_file::mapmode a)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
operator |=(mapped_file::mapmode & a,mapped_file::mapmode b)585 operator|=(mapped_file::mapmode& a, mapped_file::mapmode b)
586 {
587     return a = a | b;
588 }
589 
590 inline mapped_file::mapmode
operator &=(mapped_file::mapmode & a,mapped_file::mapmode b)591 operator&=(mapped_file::mapmode& a, mapped_file::mapmode b)
592 {
593     return a = a & b;
594 }
595 
596 inline mapped_file::mapmode
operator ^=(mapped_file::mapmode & a,mapped_file::mapmode b)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
610