8 #ifndef Sawyer_MappedBuffer_H
9 #define Sawyer_MappedBuffer_H
11 #include <Sawyer/AllocatingBuffer.h>
12 #include <Sawyer/Buffer.h>
13 #include <Sawyer/Sawyer.h>
14 #include <Sawyer/StaticBuffer.h>
16 #include <boost/algorithm/string/predicate.hpp>
17 #include <boost/filesystem.hpp>
18 #include <boost/iostreams/device/mapped_file.hpp>
19 #include <boost/lexical_cast.hpp>
20 #include <boost/serialization/access.hpp>
21 #include <boost/serialization/base_object.hpp>
22 #include <boost/serialization/nvp.hpp>
23 #include <boost/serialization/split_member.hpp>
24 #include <boost/serialization/string.hpp>
42 template<
class A,
class T>
44 boost::iostreams::mapped_file_params params_;
45 boost::iostreams::mapped_file device_;
53 friend class boost::serialization::access;
58 void save(S &s,
const unsigned )
const {
59 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Super);
60 s & boost::serialization::make_nvp(
"path", params_.path);
61 s & boost::serialization::make_nvp(
"flags", params_.flags);
62 s & boost::serialization::make_nvp(
"mode", params_.mode);
63 s & boost::serialization::make_nvp(
"offset", params_.offset);
64 s & boost::serialization::make_nvp(
"length", params_.length);
65 s & boost::serialization::make_nvp(
"new_file_size", params_.new_file_size);
68 BOOST_STATIC_ASSERT(
sizeof hint >=
sizeof params_.hint);
69 hint = (boost::uint64_t)(params_.hint);
70 s & BOOST_SERIALIZATION_NVP(hint);
76 void load(S &s,
const unsigned ) {
77 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(
Super);
78 s & boost::serialization::make_nvp(
"path", params_.path);
79 s & boost::serialization::make_nvp(
"flags", params_.flags);
80 s & boost::serialization::make_nvp(
"mode", params_.mode);
81 s & boost::serialization::make_nvp(
"offset", params_.offset);
82 s & boost::serialization::make_nvp(
"length", params_.length);
83 s & boost::serialization::make_nvp(
"new_file_size", params_.new_file_size);
86 BOOST_STATIC_ASSERT(
sizeof hint >=
sizeof params_.hint);
87 s & BOOST_SERIALIZATION_NVP(hint);
88 params_.hint = (
const char*)hint;
90 device_.open(params_);
93 BOOST_SERIALIZATION_SPLIT_MEMBER();
97 :
Super(
".MappedBuffer") {}
98 explicit MappedBuffer(
const boost::iostreams::mapped_file_params ¶ms)
99 :
Super(
".MappedBuffer"), params_(params), device_(params) {}
108 }
catch (
const std::ios_base::failure &e) {
109 if (boost::contains(e.what(),
"Invalid argument") &&
110 boost::filesystem::is_regular_file(params.path) &&
111 boost::filesystem::is_empty(params.path)) {
124 boost::iostreams::mapped_file::mapmode mode=boost::iostreams::mapped_file::readonly,
125 boost::intmax_t offset=0,
126 boost::iostreams::mapped_file::size_type length=boost::iostreams::mapped_file::max_length) {
127 boost::iostreams::mapped_file_params params(path.string());
129 params.length = length;
130 params.offset = offset;
140 Address nWritten = newBuffer->write((
const Value*)device_.data(), 0, this->size());
141 if (nWritten != this->
size()) {
142 throw std::runtime_error(
"MappedBuffer::copy() failed after copying " +
143 boost::lexical_cast<std::string>(nWritten) +
" of " +
144 boost::lexical_cast<std::string>(this->
size()) +
145 (1==this->
size()?
" value":
" values"));
151 return address >= device_.size() ?
Address(0) : (
Address(device_.size()) - address) /
sizeof(
Value);
155 if (n != this->
size())
156 throw std::runtime_error(
"resizing not allowed for MappedBuffer");
161 memcpy(buf, device_.const_data() + address, nread *
sizeof(
Value));
167 memcpy(device_.data() + address, buf, nwritten *
sizeof(
Value));
172 return (
Value*)device_.const_data();