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");
159 Address
read(Value *buf, Address address, Address n)
const {
160 Address nread = std::min(n,
available(address));
161 memcpy(buf, device_.const_data() + address, nread *
sizeof(
Value));
165 Address
write(
const Value *buf, Address address, Address n) {
166 Address nwritten = std::min(n,
available(address));
167 memcpy(device_.data() + address, buf, nwritten *
sizeof(
Value));
172 return (Value*)device_.const_data();
Address write(const Value *buf, Address address, Address n)
Writes data to a buffer.
const Value * data() const
Data for the buffer.
Buffer< A, T >::Ptr copy() const
Create a new copy of buffer data.
A Address
Type of addresses.
void resize(Address n)
Change the size of the buffer.
static Buffer< A, T >::Ptr instance(Address size)
Allocating constructor.
Reference-counting intrusive smart pointer.
Name space for the entire library.
virtual Address size() const
Size of buffer.
Address read(Value *buf, Address address, Address n) const
Reads data from a buffer.
static Buffer< A, T >::Ptr instance(const boost::iostreams::mapped_file_params ¶ms)
Map a file according to boost parameters.
Buffer< A, T > Super
Type of base class.
Address available(Address address) const
Distance to end of buffer.
static Buffer< A, T >::Ptr instance(Value *values, Address size)
Construct from caller-supplied data.
SharedPointer< Buffer > Ptr
Reference counting smart pointer.
Base class for all buffers.
static Buffer< A, T >::Ptr instance(const boost::filesystem::path &path, boost::iostreams::mapped_file::mapmode mode=boost::iostreams::mapped_file::readonly, boost::intmax_t offset=0, boost::iostreams::mapped_file::size_type length=boost::iostreams::mapped_file::max_length)
Map a file by name.