File indexing completed on 2025-01-18 09:38:51
0001
0002
0003
0004
0005
0006
0007 #ifndef BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
0008 #define BOOST_IOSTREAMS_MAPPED_FILE_HPP_INCLUDED
0009
0010 #if defined(_MSC_VER)
0011 # pragma once
0012 #endif
0013
0014 #include <boost/config.hpp> // make sure size_t is in std.
0015 #include <cstddef> // size_t.
0016 #include <string> // pathnames.
0017 #include <utility> // pair.
0018 #include <boost/config.hpp> // BOOST_MSVC.
0019 #include <boost/detail/workaround.hpp>
0020 #include <boost/iostreams/close.hpp>
0021 #include <boost/iostreams/concepts.hpp>
0022 #include <boost/iostreams/detail/config/auto_link.hpp>
0023 #include <boost/iostreams/detail/config/dyn_link.hpp>
0024 #include <boost/iostreams/detail/config/wide_streams.hpp>
0025 #include <boost/iostreams/detail/ios.hpp> // openmode, failure
0026 #include <boost/iostreams/detail/path.hpp>
0027 #include <boost/iostreams/operations_fwd.hpp>
0028 #include <boost/iostreams/positioning.hpp>
0029 #include <boost/shared_ptr.hpp>
0030 #include <boost/static_assert.hpp>
0031 #include <boost/throw_exception.hpp>
0032 #include <boost/type_traits/is_same.hpp>
0033
0034
0035 #if defined(BOOST_MSVC)
0036 # pragma warning(push)
0037 # pragma warning(disable:4251)
0038 #endif
0039 #include <boost/config/abi_prefix.hpp>
0040
0041 namespace boost { namespace iostreams {
0042
0043
0044
0045
0046 class mapped_file_source;
0047 class mapped_file_sink;
0048 class mapped_file;
0049 namespace detail { class mapped_file_impl; }
0050
0051 class mapped_file_base {
0052 public:
0053 enum mapmode {
0054 readonly = 1,
0055 readwrite = 2,
0056 priv = 4
0057 };
0058 };
0059
0060
0061 mapped_file_base::mapmode
0062 operator|(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
0063
0064 mapped_file_base::mapmode
0065 operator&(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
0066
0067 mapped_file_base::mapmode
0068 operator^(mapped_file_base::mapmode a, mapped_file_base::mapmode b);
0069
0070 mapped_file_base::mapmode
0071 operator~(mapped_file_base::mapmode a);
0072
0073 mapped_file_base::mapmode
0074 operator|=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
0075
0076 mapped_file_base::mapmode
0077 operator&=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
0078
0079 mapped_file_base::mapmode
0080 operator^=(mapped_file_base::mapmode& a, mapped_file_base::mapmode b);
0081
0082
0083
0084 namespace detail {
0085
0086 struct mapped_file_params_base {
0087 mapped_file_params_base()
0088 : flags(static_cast<mapped_file_base::mapmode>(0)),
0089 mode(), offset(0), length(static_cast<std::size_t>(-1)),
0090 new_file_size(0), hint(0)
0091 { }
0092 private:
0093 friend class mapped_file_impl;
0094 void normalize();
0095 public:
0096 mapped_file_base::mapmode flags;
0097 BOOST_IOS::openmode mode;
0098 stream_offset offset;
0099 std::size_t length;
0100 stream_offset new_file_size;
0101 const char* hint;
0102 };
0103
0104 }
0105
0106
0107
0108
0109
0110
0111
0112 template<typename Path>
0113 struct basic_mapped_file_params
0114 : detail::mapped_file_params_base
0115 {
0116 typedef detail::mapped_file_params_base base_type;
0117
0118
0119
0120 #ifndef BOOST_IOSTREAMS_NO_WIDE_STREAMS
0121 BOOST_STATIC_ASSERT((!is_same<Path, std::wstring>::value));
0122 #endif
0123
0124
0125 basic_mapped_file_params() { }
0126
0127
0128 explicit basic_mapped_file_params(const Path& p) : path(p) { }
0129
0130
0131 template<typename PathT>
0132 explicit basic_mapped_file_params(const PathT& p) : path(p) { }
0133
0134
0135 basic_mapped_file_params(const basic_mapped_file_params& other)
0136 : base_type(other), path(other.path)
0137 { }
0138
0139
0140 template<typename PathT>
0141 basic_mapped_file_params(const basic_mapped_file_params<PathT>& other)
0142 : base_type(other), path(other.path)
0143 { }
0144
0145 typedef Path path_type;
0146 Path path;
0147 };
0148
0149 typedef basic_mapped_file_params<std::string> mapped_file_params;
0150
0151
0152
0153 class BOOST_IOSTREAMS_DECL mapped_file_source : public mapped_file_base {
0154 private:
0155 struct safe_bool_helper { int x; };
0156 typedef int safe_bool_helper::* safe_bool;
0157 typedef detail::mapped_file_impl impl_type;
0158 typedef basic_mapped_file_params<detail::path> param_type;
0159 friend class mapped_file;
0160 friend class detail::mapped_file_impl;
0161 friend struct boost::iostreams::operations<mapped_file_source>;
0162 public:
0163 typedef char char_type;
0164 struct category
0165 : public source_tag,
0166 public direct_tag,
0167 public closable_tag
0168 { };
0169 typedef std::size_t size_type;
0170 typedef const char* iterator;
0171 BOOST_STATIC_CONSTANT(size_type, max_length = static_cast<size_type>(-1));
0172
0173
0174 mapped_file_source();
0175
0176
0177 template<typename Path>
0178 explicit mapped_file_source(const basic_mapped_file_params<Path>& p);
0179
0180
0181 template<typename Path>
0182 explicit mapped_file_source( const Path& path,
0183 size_type length = max_length,
0184 boost::intmax_t offset = 0 );
0185
0186
0187 mapped_file_source(const mapped_file_source& other);
0188
0189
0190
0191 template<typename Path>
0192 void open(const basic_mapped_file_params<Path>& p);
0193
0194 template<typename Path>
0195 void open( const Path& path,
0196 size_type length = max_length,
0197 boost::intmax_t offset = 0 );
0198
0199 bool is_open() const;
0200 void close();
0201 operator safe_bool() const;
0202 bool operator!() const;
0203 mapmode flags() const;
0204
0205
0206
0207 size_type size() const;
0208 const char* data() const;
0209 iterator begin() const;
0210 iterator end() const;
0211
0212
0213
0214
0215
0216 static int alignment();
0217
0218 private:
0219 void init();
0220 void open_impl(const param_type& p);
0221
0222 boost::shared_ptr<impl_type> pimpl_;
0223 };
0224
0225
0226
0227 class BOOST_IOSTREAMS_DECL mapped_file : public mapped_file_base {
0228 private:
0229 typedef mapped_file_source delegate_type;
0230 typedef delegate_type::safe_bool safe_bool;
0231 typedef basic_mapped_file_params<detail::path> param_type;
0232 friend struct boost::iostreams::operations<mapped_file >;
0233 friend class mapped_file_sink;
0234 public:
0235 typedef char char_type;
0236 struct category
0237 : public seekable_device_tag,
0238 public direct_tag,
0239 public closable_tag
0240 { };
0241 typedef mapped_file_source::size_type size_type;
0242 typedef char* iterator;
0243 typedef const char* const_iterator;
0244 BOOST_STATIC_CONSTANT(size_type, max_length = delegate_type::max_length);
0245
0246
0247 mapped_file() { }
0248
0249
0250 template<typename Path>
0251 explicit mapped_file(const basic_mapped_file_params<Path>& p);
0252
0253
0254 template<typename Path>
0255 mapped_file( const Path& path,
0256 mapmode flags,
0257 size_type length = max_length,
0258 stream_offset offset = 0 );
0259
0260
0261
0262 template<typename Path>
0263 explicit mapped_file( const Path& path,
0264 BOOST_IOS::openmode mode =
0265 BOOST_IOS::in | BOOST_IOS::out,
0266 size_type length = max_length,
0267 stream_offset offset = 0 );
0268
0269
0270 mapped_file(const mapped_file& other);
0271
0272
0273
0274 operator mapped_file_source&() { return delegate_; }
0275 operator const mapped_file_source&() const { return delegate_; }
0276
0277
0278
0279
0280 template<typename Path>
0281 void open(const basic_mapped_file_params<Path>& p);
0282
0283
0284 template<typename Path>
0285 void open( const Path& path,
0286 mapmode mode,
0287 size_type length = max_length,
0288 stream_offset offset = 0 );
0289
0290
0291
0292 template<typename Path>
0293 void open( const Path& path,
0294 BOOST_IOS::openmode mode =
0295 BOOST_IOS::in | BOOST_IOS::out,
0296 size_type length = max_length,
0297 stream_offset offset = 0 );
0298
0299 bool is_open() const { return delegate_.is_open(); }
0300 void close() { delegate_.close(); }
0301 operator safe_bool() const { return delegate_; }
0302 bool operator!() const { return !delegate_; }
0303 mapmode flags() const { return delegate_.flags(); }
0304
0305
0306
0307 size_type size() const { return delegate_.size(); }
0308 char* data() const;
0309 const char* const_data() const { return delegate_.data(); }
0310 iterator begin() const { return data(); }
0311 const_iterator const_begin() const { return const_data(); }
0312 iterator end() const;
0313 const_iterator const_end() const { return const_data() + size(); }
0314
0315
0316
0317
0318
0319 static int alignment() { return mapped_file_source::alignment(); }
0320
0321
0322
0323 void resize(stream_offset new_size);
0324 private:
0325 delegate_type delegate_;
0326 };
0327
0328
0329
0330 class BOOST_IOSTREAMS_DECL mapped_file_sink : private mapped_file {
0331 public:
0332 friend struct boost::iostreams::operations<mapped_file_sink>;
0333 using mapped_file::mapmode;
0334 using mapped_file::readonly;
0335 using mapped_file::readwrite;
0336 using mapped_file::priv;
0337 using mapped_file::char_type;
0338 struct category
0339 : public sink_tag,
0340 public direct_tag,
0341 public closable_tag
0342 { };
0343 using mapped_file::size_type;
0344 using mapped_file::iterator;
0345 using mapped_file::max_length;
0346 using mapped_file::is_open;
0347 using mapped_file::close;
0348 using mapped_file::operator safe_bool;
0349 using mapped_file::operator !;
0350 using mapped_file::flags;
0351 using mapped_file::size;
0352 using mapped_file::data;
0353 using mapped_file::begin;
0354 using mapped_file::end;
0355 using mapped_file::alignment;
0356 using mapped_file::resize;
0357
0358
0359 mapped_file_sink() { }
0360
0361
0362 template<typename Path>
0363 explicit mapped_file_sink(const basic_mapped_file_params<Path>& p);
0364
0365
0366 template<typename Path>
0367 explicit mapped_file_sink( const Path& path,
0368 size_type length = max_length,
0369 boost::intmax_t offset = 0,
0370 mapmode flags = readwrite );
0371
0372
0373 mapped_file_sink(const mapped_file_sink& other);
0374
0375
0376 template<typename Path>
0377 void open(const basic_mapped_file_params<Path>& p);
0378
0379
0380 template<typename Path>
0381 void open( const Path& path,
0382 size_type length = max_length,
0383 boost::intmax_t offset = 0,
0384 mapmode flags = readwrite );
0385 };
0386
0387
0388
0389 template<typename Path>
0390 mapped_file_source::mapped_file_source(const basic_mapped_file_params<Path>& p)
0391 { init(); open(p); }
0392
0393 template<typename Path>
0394 mapped_file_source::mapped_file_source(
0395 const Path& path, size_type length, boost::intmax_t offset)
0396 { init(); open(path, length, offset); }
0397
0398 template<typename Path>
0399 void mapped_file_source::open(const basic_mapped_file_params<Path>& p)
0400 {
0401 param_type params(p);
0402 if (params.flags) {
0403 if (params.flags != mapped_file::readonly)
0404 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
0405 } else {
0406 if (params.mode & BOOST_IOS::out)
0407 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
0408 params.mode |= BOOST_IOS::in;
0409 }
0410 open_impl(params);
0411 }
0412
0413 template<typename Path>
0414 void mapped_file_source::open(
0415 const Path& path, size_type length, boost::intmax_t offset)
0416 {
0417 param_type p(path);
0418 p.length = length;
0419 p.offset = offset;
0420 open(p);
0421 }
0422
0423
0424
0425 template<typename Path>
0426 mapped_file::mapped_file(const basic_mapped_file_params<Path>& p)
0427 { open(p); }
0428
0429 template<typename Path>
0430 mapped_file::mapped_file(
0431 const Path& path, mapmode flags,
0432 size_type length, stream_offset offset )
0433 { open(path, flags, length, offset); }
0434
0435 template<typename Path>
0436 mapped_file::mapped_file(
0437 const Path& path, BOOST_IOS::openmode mode,
0438 size_type length, stream_offset offset )
0439 { open(path, mode, length, offset); }
0440
0441 template<typename Path>
0442 void mapped_file::open(const basic_mapped_file_params<Path>& p)
0443 { delegate_.open_impl(p); }
0444
0445 template<typename Path>
0446 void mapped_file::open(
0447 const Path& path, mapmode flags,
0448 size_type length, stream_offset offset )
0449 {
0450 param_type p(path);
0451 p.flags = flags;
0452 p.length = length;
0453 p.offset = offset;
0454 open(p);
0455 }
0456
0457 template<typename Path>
0458 void mapped_file::open(
0459 const Path& path, BOOST_IOS::openmode mode,
0460 size_type length, stream_offset offset )
0461 {
0462 param_type p(path);
0463 p.mode = mode;
0464 p.length = length;
0465 p.offset = offset;
0466 open(p);
0467 }
0468
0469 inline char* mapped_file::data() const
0470 { return (flags() != readonly) ? const_cast<char*>(delegate_.data()) : 0; }
0471
0472 inline mapped_file::iterator mapped_file::end() const
0473 { return (flags() != readonly) ? data() + size() : 0; }
0474
0475
0476
0477 template<typename Path>
0478 mapped_file_sink::mapped_file_sink(const basic_mapped_file_params<Path>& p)
0479 { open(p); }
0480
0481 template<typename Path>
0482 mapped_file_sink::mapped_file_sink(
0483 const Path& path, size_type length,
0484 boost::intmax_t offset, mapmode flags )
0485 { open(path, length, offset, flags); }
0486
0487 template<typename Path>
0488 void mapped_file_sink::open(const basic_mapped_file_params<Path>& p)
0489 {
0490 param_type params(p);
0491 if (params.flags) {
0492 if (params.flags & mapped_file::readonly)
0493 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid flags"));
0494 } else {
0495 if (params.mode & BOOST_IOS::in)
0496 boost::throw_exception(BOOST_IOSTREAMS_FAILURE("invalid mode"));
0497 params.mode |= BOOST_IOS::out;
0498 }
0499 mapped_file::open(params);
0500 }
0501
0502 template<typename Path>
0503 void mapped_file_sink::open(
0504 const Path& path, size_type length,
0505 boost::intmax_t offset, mapmode flags )
0506 {
0507 param_type p(path);
0508 p.flags = flags;
0509 p.length = length;
0510 p.offset = offset;
0511 open(p);
0512 }
0513
0514
0515
0516 template<>
0517 struct operations<mapped_file_source>
0518 : boost::iostreams::detail::close_impl<closable_tag>
0519 {
0520 static std::pair<char*, char*>
0521 input_sequence(mapped_file_source& src)
0522 {
0523 return std::make_pair( const_cast<char*>(src.begin()),
0524 const_cast<char*>(src.end()) );
0525 }
0526 };
0527
0528 template<>
0529 struct operations<mapped_file>
0530 : boost::iostreams::detail::close_impl<closable_tag>
0531 {
0532 static std::pair<char*, char*>
0533 input_sequence(mapped_file& file)
0534 {
0535 return std::make_pair(file.begin(), file.end());
0536 }
0537 static std::pair<char*, char*>
0538 output_sequence(mapped_file& file)
0539 {
0540 return std::make_pair(file.begin(), file.end());
0541 }
0542 };
0543
0544 template<>
0545 struct operations<mapped_file_sink>
0546 : boost::iostreams::detail::close_impl<closable_tag>
0547 {
0548 static std::pair<char*, char*>
0549 output_sequence(mapped_file_sink& sink)
0550 {
0551 return std::make_pair(sink.begin(), sink.end());
0552 }
0553 };
0554
0555
0556
0557 inline mapped_file::mapmode
0558 operator|(mapped_file::mapmode a, mapped_file::mapmode b)
0559 {
0560 return static_cast<mapped_file::mapmode>
0561 (static_cast<int>(a) | static_cast<int>(b));
0562 }
0563
0564 inline mapped_file::mapmode
0565 operator&(mapped_file::mapmode a, mapped_file::mapmode b)
0566 {
0567 return static_cast<mapped_file::mapmode>
0568 (static_cast<int>(a) & static_cast<int>(b));
0569 }
0570
0571 inline mapped_file::mapmode
0572 operator^(mapped_file::mapmode a, mapped_file::mapmode b)
0573 {
0574 return static_cast<mapped_file::mapmode>
0575 (static_cast<int>(a) ^ static_cast<int>(b));
0576 }
0577
0578 inline mapped_file::mapmode
0579 operator~(mapped_file::mapmode a)
0580 {
0581 return static_cast<mapped_file::mapmode>(~static_cast<int>(a));
0582 }
0583
0584 inline mapped_file::mapmode
0585 operator|=(mapped_file::mapmode& a, mapped_file::mapmode b)
0586 {
0587 return a = a | b;
0588 }
0589
0590 inline mapped_file::mapmode
0591 operator&=(mapped_file::mapmode& a, mapped_file::mapmode b)
0592 {
0593 return a = a & b;
0594 }
0595
0596 inline mapped_file::mapmode
0597 operator^=(mapped_file::mapmode& a, mapped_file::mapmode b)
0598 {
0599 return a = a ^ b;
0600 }
0601
0602 } }
0603
0604 #include <boost/config/abi_suffix.hpp> // pops abi_suffix.hpp pragmas
0605 #if defined(BOOST_MSVC)
0606 # pragma warning(pop)
0607 #endif
0608
0609 #endif