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