8 #ifndef Sawyer_AddressMap_H
9 #define Sawyer_AddressMap_H
11 #include <Sawyer/Access.h>
12 #include <Sawyer/AddressSegment.h>
13 #include <Sawyer/Assert.h>
14 #include <Sawyer/BitVector.h>
15 #include <Sawyer/Callbacks.h>
16 #include <Sawyer/Interval.h>
17 #include <Sawyer/IntervalMap.h>
18 #include <Sawyer/IntervalSet.h>
19 #include <Sawyer/Sawyer.h>
21 #include <boost/algorithm/string/predicate.hpp>
22 #include <boost/cstdint.hpp>
23 #include <boost/integer_traits.hpp>
24 #include <boost/lexical_cast.hpp>
25 #include <boost/serialization/access.hpp>
26 #include <boost/serialization/base_object.hpp>
27 #include <boost/serialization/nvp.hpp>
29 #if __cplusplus >= 201103L
30 #include <type_traits>
36 template<
class AddressMap>
42 template<
class AddressMap>
50 static const MatchFlags MATCH_BACKWARD = 0x00000001;
51 static const MatchFlags MATCH_CONTIGUOUS = 0x00000002;
52 static const MatchFlags MATCH_NONCONTIGUOUS = 0x00000004;
53 static const MatchFlags MATCH_WHOLE = 0x00000008;
57 template<
class A,
class T>
64 : interval(interval), segment(segment) {}
68 virtual bool operator()(
bool chain,
const Args &) = 0;
78 template<
typename AddressMap>
94 unsigned requiredAccess_;
95 unsigned prohibitedAccess_;
96 std::string nameSubstring_;
101 : map_(map), never_(false), maxSize_(size_t(-1)), singleSegment_(false), requiredAccess_(0), prohibitedAccess_(0) {}
103 #if __cplusplus >= 201103L
106 template<typename U = AddressMap, typename = typename std::enable_if<!std::is_const<U>::value,
void>::type>
119 cc = cc.atOrAfter(*
least());
122 cc = cc.limit(
limit());
124 cc = cc.singleSegment();
132 operator AddressMapConstraints<const AddressMap>()
const {
133 AddressMapConstraints<const AddressMap> cc(map_);
144 cc = cc.atOrAfter(*
least());
147 cc = cc.limit(
limit());
149 cc = cc.singleSegment();
159 void print(std::ostream &out)
const {
160 out <<
"{map=" <<map_;
164 out <<
", least=" <<*least_;
166 out <<
", greatest=" <<*greatest_;
169 AddressInterval a = *anchored_;
178 if (maxSize_ !=
size_t(-1))
179 out <<
", limit=" <<maxSize_;
181 out <<
", single-segment";
182 if (requiredAccess_!=0) {
184 <<((requiredAccess_ & Access::READABLE) ?
"r" :
"")
185 <<((requiredAccess_ & Access::WRITABLE) ?
"w" :
"")
186 <<((requiredAccess_ & Access::EXECUTABLE) ?
"x" :
"")
187 <<((requiredAccess_ & Access::IMMUTABLE) ?
"i" :
"");
188 unsigned other = requiredAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
192 if (prohibitedAccess_!=0) {
194 <<((prohibitedAccess_ & Access::READABLE) ?
"r" :
"")
195 <<((prohibitedAccess_ & Access::WRITABLE) ?
"w" :
"")
196 <<((prohibitedAccess_ & Access::EXECUTABLE) ?
"x" :
"")
197 <<((prohibitedAccess_ & Access::IMMUTABLE) ?
"i" :
"");
198 unsigned other = prohibitedAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
202 if (!nameSubstring_.empty()) {
204 for (
char ch: nameSubstring_) {
206 case '\a': out <<
"\\a";
break;
207 case '\b': out <<
"\\b";
break;
208 case '\t': out <<
"\\t";
break;
209 case '\n': out <<
"\\n";
break;
210 case '\v': out <<
"\\v";
break;
211 case '\f': out <<
"\\f";
break;
212 case '\r': out <<
"\\r";
break;
213 case '\"': out <<
"\\\"";
break;
214 case '\\': out <<
"\\\\";
break;
220 snprintf(buf,
sizeof(buf),
"\\%03o", (
unsigned)(
unsigned char)ch);
227 if (!segmentPredicates_.isEmpty())
244 retval.requiredAccess_ |= bits;
251 retval.prohibitedAccess_ |= bits;
262 ASSERT_require(nameSubstring_.empty() || nameSubstring_==s);
264 retval.nameSubstring_ = s;
276 retval.never_ =
true;
283 retval.anchored_ = anchored_ ? *anchored_ & AddressInterval(x) : AddressInterval(x);
284 return retval.anchored_->isEmpty() ? retval.
none() : retval;
290 retval.anchored_ = anchored_ ? *anchored_ & x : x;
297 retval.maxSize_ = std::min(maxSize_, x);
298 return 0 == retval.maxSize_ ? retval.
none() : retval;
305 retval.least_ = std::max(*least_, least);
307 retval.least_ =
least;
309 if (greatest_ && *greatest_ < *retval.least_)
318 retval.greatest_ = std::min(*greatest_, greatest);
322 if (least_ && *least_ > *retval.greatest_)
334 return lo<=hi ? within(Sawyer::Container::Interval<Address>::hull(lo, hi)) :
none();
344 return x==boost::integer_traits<Address>::const_max ?
none() :
atOrAfter(x+1);
349 return x==boost::integer_traits<Address>::const_min ?
none() :
atOrBefore(x-1);
355 retval.singleSegment_ =
true;
364 retval.segmentPredicates_.append(p);
370 retval.segmentPredicates_.append(predicates);
379 return requiredAccess_;
384 return prohibitedAccess_;
389 return nameSubstring_;
432 return singleSegment_;
437 return segmentPredicates_;
449 (requiredAccess_ || prohibitedAccess_ || !nameSubstring_.empty() || maxSize_!=size_t(-1) ||
450 singleSegment_ || !segmentPredicates_.isEmpty()));
458 c.greatest_ = greatest_;
459 c.anchored_ = anchored_;
460 c.maxSize_ = maxSize_;
467 boost::iterator_range<typename AddressMapTraits<AddressMap>::NodeIterator>
468 nodes(MatchFlags flags=0)
const {
469 return map_->
nodes(*
this, flags);
472 boost::iterator_range<typename AddressMapTraits<AddressMap>::SegmentIterator>
473 segments(MatchFlags flags=0)
const {
474 return map_->
segments(*
this, flags);
477 Optional<typename AddressMap::Address>
478 next(MatchFlags flags=0)
const {
479 return map_->
next(*
this, flags);
483 available(MatchFlags flags=0)
const {
488 exists(MatchFlags flags=0)
const {
489 return map_->
exists(*
this, flags);
492 typename AddressMapTraits<AddressMap>::NodeIterator
493 findNode(MatchFlags flags=0)
const {
494 return map_->
findNode(*
this, flags);
497 template<
typename Functor>
499 traverse(Functor &functor, MatchFlags flags=0)
const {
500 return map_->
traverse(functor, *
this, flags);
503 traverse(
typename AddressMap::Visitor &visitor, MatchFlags flags=0)
const {
504 return map_->template traverse<typename AddressMap::Visitor>(visitor, *
this, flags);
509 return map_->
read(buf, *
this, flags);
513 read(std::vector<typename AddressMap::Value> &buf ,
514 MatchFlags flags=0)
const {
515 return map_->
read(buf, *
this, flags);
520 return map_->
write(buf, *
this, flags);
524 write(
const std::vector<typename AddressMap::Value> &buf, MatchFlags flags=0) {
525 return map_->
write(buf, *
this, flags);
529 prune(MatchFlags flags=0)
const {
530 return map_->
prune(*
this, flags);
534 keep(MatchFlags flags=0)
const {
535 return map_->
keep(*
this, flags);
539 changeAccess(
unsigned requiredAccess,
unsigned prohibitedAccess, MatchFlags flags=0)
const {
540 return map_->
changeAccess(requiredAccess, prohibitedAccess, *
this, flags);
547 namespace AddressMapImpl {
550 template<
class A,
class T>
558 friend class boost::serialization::access;
561 void serialize(S&,
const unsigned ) {
568 ASSERT_forbid(leftInterval.
isEmpty());
569 ASSERT_always_forbid(rightInterval.
isEmpty());
570 ASSERT_require(leftInterval.
greatest() + 1 == rightInterval.
least());
572 leftSegment.
name() == rightSegment.
name() &&
578 ASSERT_forbid(interval.
isEmpty());
579 ASSERT_require(interval.
contains(splitPoint));
580 Segment right = segment;
586 ASSERT_always_forbid(interval.
isEmpty());
587 ASSERT_always_require(interval.
contains(splitPoint));
592 template<
class AddressMap>
597 boost::iterator_range<NodeIterator> nodes_;
605 template<
class AddressMap>
611 return amap.
nodes().end();
615 return amap.
nodes().end();
618 return amap.
nodes().end();
625 if (lb==amap.
nodes().end())
627 minAddr = std::max(*c.
least(), lb->key().least());
631 Iterator lb = amap.
nodes().begin();
632 if (lb!=amap.
nodes().end())
633 minAddr = lb->key().least();
643 template<
class AddressMap>
644 typename AddressMapTraits<AddressMap>::NodeIterator
645 constraintUpperBound(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
bool useAnchor,
647 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
648 if (amap.isEmpty() || c.neverMatches())
649 return amap.nodes().begin();
651 if (useAnchor && c.isAnchored()) {
652 if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
653 return amap.nodes().begin();
654 Iterator ub = amap.findPrior(c.anchored().greatest());
655 if (ub==amap.nodes().end() || c.anchored().greatest() > ub->key().greatest())
656 return amap.nodes().begin();
657 maxAddr = c.anchored().greatest();
662 Iterator ub = amap.findPrior(*c.greatest());
663 if (ub==amap.nodes().end())
664 return amap.nodes().begin();
665 maxAddr = std::min(ub->key().greatest(), *c.greatest());
669 maxAddr = amap.hull().greatest();
670 return amap.nodes().end();
674 template<
class AddressMap>
676 isSatisfied(
const typename AddressMap::Node &node,
const AddressMapConstraints<AddressMap> &c) {
680 const Segment &segment = node.value();
681 if (!segment.isAccessible(c.required(), c.prohibited()))
683 if (!boost::contains(segment.name(), c.substr()))
685 if (!c.segmentPredicates().apply(
true,
typename SegmentPredicate<Address, Value>::Args(node.key(), node.value())))
691 template<
class AddressMap>
692 MatchedConstraints<AddressMap>
693 matchForward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
695 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
696 MatchedConstraints<AddressMap> retval;
697 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
698 if (c.neverMatches() || amap.isEmpty())
703 Iterator begin = constraintLowerBound(amap, c,
true, minAddr );
704 if (begin == amap.nodes().end())
709 Iterator end = constraintUpperBound(amap, c,
false, maxAddr );
710 if (end==amap.nodes().begin())
714 while (begin!=end && !isSatisfied(*begin, c)) {
721 minAddr = std::max(minAddr, begin->key().least());
724 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
725 Address addr = minAddr;
726 Iterator iter = begin;
727 size_t nElmtsFound = 0;
728 for (; iter!=end; ++iter) {
730 if (c.isSingleSegment())
732 if ((flags & MATCH_CONTIGUOUS)!=0 && addr+1 != iter->key().least())
734 if (!isSatisfied(*iter, c)) {
735 if ((flags & MATCH_WHOLE)!=0)
740 size_t nElmtsHere = iter->key().greatest() + 1 - std::max(minAddr, iter->key().least());
741 if (nElmtsFound + nElmtsHere >= c.limit()) {
742 size_t nNeed = c.limit() - nElmtsFound;
743 addr = std::max(minAddr, iter->key().least()) + nNeed - 1;
747 addr = iter->key().greatest();
748 nElmtsFound += nElmtsHere;
751 maxAddr = std::min(maxAddr, addr);
756 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
761 template<
class AddressMap>
762 MatchedConstraints<AddressMap>
763 matchBackward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
765 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
766 MatchedConstraints<AddressMap> retval;
767 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
768 if (c.neverMatches() || amap.isEmpty())
773 Iterator begin = constraintLowerBound(amap, c,
false, minAddr );
774 if (begin == amap.nodes().end())
779 Iterator end = constraintUpperBound(amap, c,
true, maxAddr );
780 if (end==amap.nodes().begin())
785 Iterator prev = end; --prev;
786 if (isSatisfied(*prev, c)) {
787 maxAddr = std::min(maxAddr, prev->key().greatest());
799 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
800 Address addr = maxAddr;
802 size_t nElmtsFound = 0;
803 for (; iter!=begin; --iter) {
804 Iterator prev = iter; --prev;
806 if (c.isSingleSegment())
808 if ((flags & MATCH_CONTIGUOUS)!=0 && prev->key().greatest()+1 != addr)
810 if (!isSatisfied(*prev, c)) {
811 if ((flags & MATCH_WHOLE)!=0)
816 size_t nElmtsHere = std::min(maxAddr, prev->key().greatest()) - prev->key().least() + 1;
817 if (nElmtsFound + nElmtsHere >= c.limit()) {
818 size_t nNeed = c.limit() - nElmtsFound;
819 addr = std::min(maxAddr, prev->key().greatest()) - nNeed + 1;
823 addr = prev->key().least();
824 nElmtsFound += nElmtsHere;
827 minAddr = std::max(minAddr, addr);
832 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
837 template<
class AddressMap>
838 MatchedConstraints<AddressMap>
839 matchConstraints(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
840 if ((flags & MATCH_BACKWARD) != 0)
841 return matchBackward(amap, c, flags);
842 return matchForward(amap, c, flags);
1002 template<
class A,
class T = boost::u
int8_t>
1020 friend class boost::serialization::access;
1023 void serialize(S &s,
const unsigned ) {
1024 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
1048 for (Segment &segment: this->
values()) {
1049 if (
const typename Buffer::Ptr &buffer = segment.buffer())
1050 buffer->copyOnWrite(
true);
1314 for (
const Node &node:
nodes()) {
1316 const Segment &segment = node.value();
1317 if (segment.
buffer()==NULL) {
1318 throw std::runtime_error(
"AddressMap null buffer for interval [" +
1319 boost::lexical_cast<std::string>(interval.
least()) +
1320 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"]");
1323 if (bufAvail < interval.
size()) {
1324 throw std::runtime_error(
"AddressMap segment at [" + boost::lexical_cast<std::string>(interval.
least()) +
1325 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"] points to only " +
1326 boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?
" value":
" values") +
1327 " but the interval size is " + boost::lexical_cast<std::string>(interval.
size()));
1346 boost::iterator_range<ConstSegmentIterator>
segments()
const {
return this->
values(); }
1368 boost::iterator_range<ConstSegmentIterator>
1370 using namespace AddressMapImpl;
1371 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1372 flags |= MATCH_CONTIGUOUS;
1373 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1374 return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1377 boost::iterator_range<SegmentIterator>
1379 using namespace AddressMapImpl;
1380 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1381 flags |= MATCH_CONTIGUOUS;
1382 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1383 return boost::iterator_range<SegmentIterator>(m.nodes_);
1416 boost::iterator_range<ConstNodeIterator>
1418 using namespace AddressMapImpl;
1419 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1420 flags |= MATCH_CONTIGUOUS;
1421 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1425 boost::iterator_range<NodeIterator>
1427 using namespace AddressMapImpl;
1428 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1429 flags |= MATCH_CONTIGUOUS;
1430 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1474 using namespace AddressMapImpl;
1475 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1476 flags |= MATCH_CONTIGUOUS;
1477 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c.
limit(1), flags);
1488 using namespace AddressMapImpl;
1489 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1490 flags |= MATCH_CONTIGUOUS;
1491 return matchConstraints(*
this, c, flags).interval_;
1504 return next(c, flags);
1543 MatchFlags flags=0)
const {
1545 ASSERT_forbid2(nValues == 0,
"cannot determine if this is an overflow or intentional");
1547 if (restriction.isEmpty())
1550 if (0 == (flags & MATCH_BACKWARD)) {
1551 Address minAddr = restriction.least();
1552 while (minAddr <= restriction.greatest()) {
1556 minAddr = alignUp(interval.
least(), alignment);
1557 Address maxAddr = minAddr + (nValues-1);
1558 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1559 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1561 maxAddr <= restriction.greatest()) {
1571 ASSERT_require((flags & MATCH_BACKWARD) != 0);
1572 Address maxAddr = restriction.greatest();
1573 while (maxAddr >= restriction.least()) {
1577 Address minAddr = alignDown(interval.
greatest() - (nValues-1), alignment);
1578 maxAddr = minAddr + (nValues-1);
1579 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1580 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1582 minAddr >= restriction.least()) {
1587 maxAddr = interval.
least() - 1;
1622 template<
typename Functor>
1624 using namespace AddressMapImpl;
1625 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1626 for (
const Node &node: m.nodes_) {
1628 if (!functor(*
this, part))
1633 template<
typename Functor>
1635 using namespace AddressMapImpl;
1636 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1637 for (
const Node &node: m.nodes_) {
1639 if (!functor(*
this, part))
1645 traverse<Visitor>(visitor, c, flags);
1648 traverse<Visitor>(visitor, c, flags);
1692 using namespace AddressMapImpl;
1693 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be read");
1694 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1695 flags |= MATCH_CONTIGUOUS;
1696 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1698 for (
const Node &node: m.nodes_) {
1700 ASSERT_forbid(part.
isEmpty());
1701 Address bufferOffset = part.
least() - node.
key().least() + node.
value().offset();
1702 Address nValues = node.
value().buffer()->read(buf, bufferOffset, part.
size());
1703 if (nValues != part.
size()) {
1705 ASSERT_not_reachable(
"something is wrong with the memory map");
1753 using namespace AddressMapImpl;
1754 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be written");
1755 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1756 flags |= MATCH_CONTIGUOUS;
1757 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
prohibit(Access::IMMUTABLE), flags);
1759 for (Node &node: m.nodes_) {
1760 Segment &segment = node.
value();
1762 ASSERT_forbid(part.
isEmpty());
1764 ASSERT_not_null(buffer);
1766 if (buffer->copyOnWrite()) {
1768 ASSERT_not_null(newBuffer);
1769 for (NodeIterator iter=this->
lowerBound(node.
key().least()); iter!=
nodes().end(); ++iter) {
1770 if (iter->value().buffer() == buffer)
1771 iter->value().buffer(newBuffer);
1776 Address bufferOffset = part.
least() - node.
key().least() + segment.
offset();
1777 Address nValues = buffer->write(buf, bufferOffset, part.
size());
1778 if (nValues != part.
size()) {
1780 ASSERT_not_reachable(
"something is wrong with the memory map");
1807 using namespace AddressMapImpl;
1809 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1810 flags |= MATCH_NONCONTIGUOUS;
1811 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1812 for (
const Node &node: m.nodes_) {
1813 if (isSatisfied(node, c))
1814 toErase.
insert(node.
key() & m.interval_);
1817 this->
erase(interval);
1834 using namespace AddressMapImpl;
1835 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1836 flags |= MATCH_NONCONTIGUOUS;
1838 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1839 for (
const Node &node: m.nodes_) {
1840 if (isSatisfied(node, c))
1841 toKeep.
insert(node.
key() & m.interval_);
1845 this->
erase(interval);
1868 MatchFlags flags=0) {
1869 using namespace AddressMapImpl;
1870 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1871 flags |= MATCH_NONCONTIGUOUS;
1872 typedef std::pair<Sawyer::Container::Interval<Address>, Segment> ISPair;
1873 std::vector<ISPair> newSegments;
1874 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1875 for (Node &node: m.nodes_) {
1876 Segment &segment = node.
value();
1877 if (isSatisfied(node, c)) {
1878 unsigned newAccess = (segment.
accessibility() | requiredAccess) & ~prohibitedAccess;
1880 if (toChange == node.
key()) {
1883 Segment newSegment(segment);
1886 newSegments.push_back(ISPair(toChange, newSegment));
1890 for (
const ISPair &pair: newSegments)
1891 this->
insert(pair.first, pair.second);
1896 static Address alignUp(Address x, Address alignment) {
1897 return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1900 static Address alignDown(Address x, Address alignment) {
1901 return alignment>0 && x%alignment!=0 ? (x/alignment)*alignment : x;
Base class for testing segment constraints.
unsigned required() const
Accessibility bits that are required to be set.
Interval lastUnmapped(typename Interval::Value maxAddr) const
Find the last unmapped region.
unsigned MatchFlags
Flags for matching constraints.
AddressMapConstraints< const AddressMap > substr(const std::string &x) const
Constraint: segment name substring.
NodeIterator findNode(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Find node containing address.
boost::iterator_range< NodeIterator > nodes(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Nodes that overlap with constraints.
const Optional< Address > & least() const
Least possible address.
AddressMapConstraints limit(size_t x) const
Limit matching length.
AddressMapConstraints at(Address x) const
Anchor at a certain address.
A Address
Type for addresses.
AddressMapConstraints< const AddressMap > access(unsigned x) const
Constraint: required and prohibited access bits.
An associative container whose keys are non-overlapping intervals.
AddressMapConstraints< AddressMap > limit(size_t x)
Constraint: limit matched size.
Optional< Address > next(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Minimum or maximum address that satisfies constraints.
Value size() const
Size of interval.
AddressMapConstraints singleSegment() const
Limit matching to single segment.
AddressMapConstraints addressConstraints() const
Construct new constraints from existing address constraints.
bool neverMatches() const
Returns true if the constraint is not allowed to match anything.
AddressMapConstraints< const AddressMap > singleSegment() const
Constraint: single segment.
bool isEmpty() const
True if interval is empty.
Super::ConstIntervalIterator ConstIntervalIterator
Iterates over address intervals in the map.
Value & value()
Value part of key/value node.
AddressMapConstraints< AddressMap > atOrAfter(Address x)
Constraint: address lower bound.
void prune(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Prune away addresses that match constraints.
Base class for traversals.
AddressMapConstraints< AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p)
Constraint: arbitrary segment constraint.
AddressMapConstraints substr(const std::string &s) const
Require certain segment names.
T Value
Type of data stored in the address space.
boost::iterator_range< SegmentIterator > segments()
Iterator range for all segments.
AddressMapConstraints segmentPredicate(SegmentPredicate< Address, Value > *p) const
Limit segments.
AddressMapConstraints< const AddressMap > at(Address x) const
Constraint: anchor point.
AddressMapConstraints< AddressMap > access(unsigned x)
Constraint: required and prohibited access bits.
AddressMapConstraints< const AddressMap > before(Address x) const
Constraint: address upper bound.
virtual Address available(Address address) const =0
Distance to end of buffer.
boost::iterator_range< ConstNodeIterator > nodes() const
Iterator range for nodes.
AddressMapConstraints any() const
No constraints.
Buffer< A, T >::Ptr buffer() const
Property: buffer.
boost::iterator_range< ConstSegmentIterator > segments() const
Iterator range for all segments.
Sawyer::Container::Interval< Address > write(const std::vector< Value > &buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
AddressMapConstraints< const AddressMap > prohibit(unsigned x) const
Constraint: prohibited access bits.
A homogeneous interval of an address space.
AddressMapConstraints< AddressMap > before(Address x)
Constraint: address upper bound.
AddressSegment< A, T > Segment
Type of segments stored by this map.
AddressMapConstraints< const AddressMap > atOrBefore(Address x) const
Constraint: address upper bound.
Super::ValueIterator SegmentIterator
Iterates over segments in the map.
Optional< Address > findFreeSpace(size_t nValues, size_t alignment=1, Sawyer::Container::Interval< Address > restriction=Sawyer::Container::Interval< Address >::whole(), MatchFlags flags=0) const
Find free space.
AddressMapConstraints< AddressMap > singleSegment()
Constraint: single segment.
Interval::Value size() const
Returns the number of values represented by this container.
bool isEmpty() const
Determine if the container is empty.
const Optional< Address > & greatest() const
Greatest possible address.
void traverse(Visitor &visitor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
AddressMapConstraints< const AddressMap > require(unsigned x) const
Constraint: required access bits.
A container holding a set of values.
AddressMapConstraints within(const Sawyer::Container::Interval< Address > &x) const
Limit addresses.
boost::iterator_range< ConstSegmentIterator > segments(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Segments that overlap with constraints.
void insert(const Interval2 &interval)
Insert specified values.
Super::ConstValueIterator ConstSegmentIterator
Iterators over segments in the map.
Reference-counting intrusive smart pointer.
BitVector & fromInteger(const BitRange &range, boost::uint64_t value)
Obtain bits from an integer.
Name space for the entire library.
Bidirectional iterator over key/value nodes.
Sawyer::Container::Interval< Address > write(const Value *buf, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Writes data from the supplied buffer.
AddressInterval anchored() const
Returns the anchor points.
AddressMapConstraints< AddressMap > require(unsigned x)
Constraint: required access bits.
boost::iterator_range< ValueIterator > values()
Iterators for traversing values.
bool exists(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Determines if an address exists with the specified constraints.
const std::string & substr() const
Section name substring.
friend std::ostream & operator<<(std::ostream &out, const AddressMapConstraints &x)
Print constraints in a human readable form.
bool contains(const Interval &other) const
Containment predicate.
AddressMapConstraints< AddressMap > baseSize(Address base, Address size)
Constraint: address lower and upper bounds.
void traverse(Functor &functor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
void checkConsistency() const
Check map consistency.
AddressMapConstraints< AddressMap > within(Address x, Address y)
Constraint: address lower and upper bounds.
const Callbacks< SegmentPredicate< Address, Value > * > segmentPredicates() const
Returns the segment predicates.
T least() const
Returns lower limit.
Sawyer::Container::Interval< Address > read(Value *buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
const std::string & name() const
Property: name.
AddressMapConstraints< AddressMap > within(const Sawyer::Container::Interval< Address > &x)
Constraint: address lower and upper bounds.
AddressMapConstraints atOrAfter(Address least) const
Limit addresses.
unsigned accessibility() const
Property: access rights.
AddressMapConstraints< const AddressMap > any() const
Constraint: matches anything.
AddressMapConstraints none() const
Constraints that match nothing.
void erase(const Interval &erasure)
Erase the specified interval.
Bidirectional iterator over values.
AddressMapConstraints within(Address lo, Address hi) const
Limit addresses.
AddressMapConstraints< const AddressMap > baseSize(Address base, Address size) const
Constraint: address lower and upper bounds.
AddressMapConstraints< AddressMap > atOrBefore(Address x)
Constraint: address upper bound.
void insert(Interval key, Value value, bool makeHole=true)
Insert a key/value pair.
unsigned prohibited() const
Accessibility bits that are required to be clear.
A mapping from address space to values.
static Interval whole()
Construct an interval that covers the entire domain.
AddressMapConstraints< AddressMap > at(const Sawyer::Container::Interval< Address > &x)
Constraint: anchored interval.
AddressMapConstraints access(unsigned bits) const
Require and prohibit certain access permissions.
static Interval hull(T v1, T v2)
Construct an interval from two endpoints.
Super::Node Node
Storage node containing interval/segment pair.
ConstNodeIterator findNode(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Find node containing address.
AddressMapConstraints< AddressMap > after(Address x)
Constraint: address lower bound.
Sawyer::Container::Interval< Address > read(std::vector< Value > &buf, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Reads data into the supplied buffer.
void changeAccess(unsigned requiredAccess, unsigned prohibitedAccess, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Change access bits for addresses that match constraints.
Base class for all buffers.
AddressMap * map() const
Returns a pointer to the memory map for this constraint object.
size_t limit() const
Size limit.
AddressMapConstraints< const AddressMap > within(const Sawyer::Container::Interval< Address > &x) const
Constraint: address lower and upper bounds.
bool isAnchored() const
Determines whether constraints are anchored to an address.
AddressMapConstraints after(Address x) const
Limit addresses.
AddressMapConstraints require(unsigned bits) const
Require certain access permissions.
const Key & key() const
Key part of key/value node.
AddressMapConstraints< const AddressMap > segmentPredicate(SegmentPredicate< Address, Value > *p) const
Constraint: arbitrary segment constraint.
boost::iterator_range< NodeIterator > nodes()
Iterators for traversing nodes.
AddressMapConstraints prohibit(unsigned bits) const
Prohibit certain access permissions.
Bidirectional iterator over values.
Sawyer::Container::Interval< Address > unmapped(Address boundary, MatchFlags flags=0) const
Find unmapped interval.
Constraints are used to select addresses from a memory map.
AddressMapConstraints before(Address x) const
Limit addreses.
AddressMapConstraints baseSize(Address base, Address size) const
Limit addresses.
AddressMapConstraints< AddressMap > none()
Constraint: matches nothing.
boost::iterator_range< ConstIntervalIterator > intervals() const
Iterator range for all intervals actually stored by this set.
AddressMapConstraints(AddressMap *map)
Construct a constraint that matches everything.
bool isSingleSegment() const
Returns true if the single-segment constraint is set.
Super::ConstNodeIterator ConstNodeIterator
Iterates over address interval/segment pairs in the map.
A offset() const
Property: buffer offset.
boost::iterator_range< NodeIterator > nodes()
Iterator range for nodes.
AddressMapConstraints atOrBefore(Address greatest) const
Limit addresses.
Super::NodeIterator NodeIterator
Iterates over address interval, segment pairs in the map.
AddressMapConstraints< AddressMap > substr(const std::string &x)
Constraint: segment name substring.
AddressMapConstraints< const AddressMap > atOrAfter(Address x) const
Constraint: address lower bound.
void keep(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Keep only addresses that match constraints.
Sawyer::Container::Interval< Address > available(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Adress interval that satisfies constraints.
Bidirectional iterator over keys.
AddressMapConstraints< const AddressMap > at(const Sawyer::Container::Interval< Address > &x) const
Constraint: anchored interval.
bool hasNonAddressConstraints() const
Determines whether non-address constraints are present.
AddressMapConstraints< const AddressMap > after(Address x) const
Constraint: address lower bound.
size_t nIntervals() const
Number of nodes in the container.
NodeIterator lowerBound(const typename Interval::Value &scalar)
Find the first node whose interval ends at or above the specified scalar key.
AddressMapConstraints at(const Sawyer::Container::Interval< Address > &x) const
Anchor at a certain interval.
AddressMapConstraints< const AddressMap > none() const
Constraint: matches nothing.
T greatest() const
Returns upper limit.
void traverse(Functor &functor, const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Invoke a function on each address interval.
AddressMapConstraints< const AddressMap > within(Address x, Address y) const
Constraint: address lower and upper bounds.
Interval firstUnmapped(typename Interval::Value minAddr) const
Find the first unmapped region.
AddressMapConstraints< const AddressMap > limit(size_t x) const
Constraint: limit matched size.
Address nSegments() const
Number of segments contained in the map.
void print(std::ostream &out) const
Print constraints in a human readable form.
void traverse(Visitor &visitor, const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Invoke a function on each address interval.
AddressMapConstraints< AddressMap > any()
Constraint: matches anything.
AddressMapConstraints< AddressMap > prohibit(unsigned x)
Constraint: prohibited access bits.
boost::iterator_range< SegmentIterator > segments(const AddressMapConstraints< AddressMap > &c, MatchFlags flags=0)
Iterator range for all segments.
AddressMapConstraints< AddressMap > at(Address x)
Constraint: anchor point.
std::string toHex(const BitRange &range) const
Convert to a hexadecimal string.
boost::iterator_range< ConstNodeIterator > nodes(const AddressMapConstraints< const AddressMap > &c, MatchFlags flags=0) const
Nodes that overlap with constraints.
Bidirectional iterator over key/value nodes.
AddressMap(const AddressMap &other, bool copyOnWrite=false)
Copy constructor.
AddressMap()
Constructs an empty address map.