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/foreach.hpp>
24 #include <boost/integer_traits.hpp>
25 #include <boost/lexical_cast.hpp>
26 #include <boost/serialization/access.hpp>
27 #include <boost/serialization/base_object.hpp>
28 #include <boost/serialization/nvp.hpp>
33 template<
class AddressMap>
39 template<
class AddressMap>
47 static const MatchFlags MATCH_BACKWARD = 0x00000001;
48 static const MatchFlags MATCH_CONTIGUOUS = 0x00000002;
49 static const MatchFlags MATCH_NONCONTIGUOUS = 0x00000004;
50 static const MatchFlags MATCH_WHOLE = 0x00000008;
54 template<
class A,
class T>
61 : interval(interval), segment(segment) {}
65 virtual bool operator()(
bool chain,
const Args &) = 0;
75 template<
typename AddressMap>
91 unsigned requiredAccess_;
92 unsigned prohibitedAccess_;
93 std::string nameSubstring_;
98 : map_(map), never_(false), maxSize_(size_t(-1)), singleSegment_(false), requiredAccess_(0), prohibitedAccess_(0) {}
113 cc = cc.atOrAfter(*
least());
116 cc = cc.limit(
limit());
118 cc = cc.singleSegment();
127 void print(std::ostream &out)
const {
128 out <<
"{map=" <<map_;
132 out <<
", least=" <<*least_;
134 out <<
", greatest=" <<*greatest_;
137 AddressInterval a = *anchored_;
146 if (maxSize_ !=
size_t(-1))
147 out <<
", limit=" <<maxSize_;
149 out <<
", single-segment";
150 if (requiredAccess_!=0) {
152 <<((requiredAccess_ & Access::READABLE) ?
"r" :
"")
153 <<((requiredAccess_ & Access::WRITABLE) ?
"w" :
"")
154 <<((requiredAccess_ & Access::EXECUTABLE) ?
"x" :
"")
155 <<((requiredAccess_ & Access::IMMUTABLE) ?
"i" :
"");
156 unsigned other = requiredAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
160 if (prohibitedAccess_!=0) {
162 <<((prohibitedAccess_ & Access::READABLE) ?
"r" :
"")
163 <<((prohibitedAccess_ & Access::WRITABLE) ?
"w" :
"")
164 <<((prohibitedAccess_ & Access::EXECUTABLE) ?
"x" :
"")
165 <<((prohibitedAccess_ & Access::IMMUTABLE) ?
"i" :
"");
166 unsigned other = prohibitedAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
170 if (!nameSubstring_.empty()) {
172 BOOST_FOREACH (
char ch, nameSubstring_) {
174 case '\a': out <<
"\\a";
break;
175 case '\b': out <<
"\\b";
break;
176 case '\t': out <<
"\\t";
break;
177 case '\n': out <<
"\\n";
break;
178 case '\v': out <<
"\\v";
break;
179 case '\f': out <<
"\\f";
break;
180 case '\r': out <<
"\\r";
break;
181 case '\"': out <<
"\\\"";
break;
182 case '\\': out <<
"\\\\";
break;
188 sprintf(buf,
"\\%03o", (
unsigned)(
unsigned char)ch);
195 if (!segmentPredicates_.isEmpty())
212 retval.requiredAccess_ |= bits;
219 retval.prohibitedAccess_ |= bits;
230 ASSERT_require(nameSubstring_.empty() || nameSubstring_==s);
232 retval.nameSubstring_ = s;
244 retval.never_ =
true;
251 retval.anchored_ = anchored_ ? *anchored_ & AddressInterval(x) : AddressInterval(x);
252 return retval.anchored_->isEmpty() ? retval.
none() : retval;
258 retval.anchored_ = anchored_ ? *anchored_ & x : x;
265 retval.maxSize_ = std::min(maxSize_, x);
266 return 0 == retval.maxSize_ ? retval.
none() : retval;
273 retval.least_ = std::max(*least_, least);
275 retval.least_ =
least;
277 if (greatest_ && *greatest_ < *retval.least_)
286 retval.greatest_ = std::min(*greatest_, greatest);
290 if (least_ && *least_ > *retval.greatest_)
302 return lo<=hi ? within(Sawyer::Container::Interval<Address>::hull(lo, hi)) :
none();
312 return x==boost::integer_traits<Address>::const_max ?
none() :
atOrAfter(x+1);
317 return x==boost::integer_traits<Address>::const_min ?
none() :
atOrBefore(x-1);
323 retval.singleSegment_ =
true;
332 retval.segmentPredicates_.append(p);
338 retval.segmentPredicates_.append(predicates);
347 return requiredAccess_;
352 return prohibitedAccess_;
357 return nameSubstring_;
400 return singleSegment_;
405 return segmentPredicates_;
417 (requiredAccess_ || prohibitedAccess_ || !nameSubstring_.empty() || maxSize_!=size_t(-1) ||
418 singleSegment_ || !segmentPredicates_.isEmpty()));
426 c.greatest_ = greatest_;
427 c.anchored_ = anchored_;
428 c.maxSize_ = maxSize_;
435 boost::iterator_range<typename AddressMapTraits<AddressMap>::NodeIterator>
436 nodes(MatchFlags flags=0)
const {
437 return map_->
nodes(*
this, flags);
440 boost::iterator_range<typename AddressMapTraits<AddressMap>::SegmentIterator>
441 segments(MatchFlags flags=0)
const {
442 return map_->
segments(*
this, flags);
445 Optional<typename AddressMap::Address>
446 next(MatchFlags flags=0)
const {
447 return map_->
next(*
this, flags);
451 available(MatchFlags flags=0)
const {
456 exists(MatchFlags flags=0)
const {
457 return map_->
exists(*
this, flags);
460 typename AddressMapTraits<AddressMap>::NodeIterator
461 findNode(MatchFlags flags=0)
const {
462 return map_->
findNode(*
this, flags);
465 template<
typename Functor>
467 traverse(Functor &functor, MatchFlags flags=0)
const {
468 return map_->
traverse(functor, *
this, flags);
471 traverse(
typename AddressMap::Visitor &visitor, MatchFlags flags=0)
const {
472 return map_->template traverse<typename AddressMap::Visitor>(visitor, *
this, flags);
477 return map_->
read(buf, *
this, flags);
481 read(std::vector<typename AddressMap::Value> &buf ,
482 MatchFlags flags=0)
const {
483 return map_->
read(buf, *
this, flags);
488 return map_->
write(buf, *
this, flags);
492 write(
const std::vector<typename AddressMap::Value> &buf, MatchFlags flags=0) {
493 return map_->
write(buf, *
this, flags);
497 prune(MatchFlags flags=0)
const {
498 return map_->
prune(*
this, flags);
502 keep(MatchFlags flags=0)
const {
503 return map_->
keep(*
this, flags);
507 changeAccess(
unsigned requiredAccess,
unsigned prohibitedAccess, MatchFlags flags=0)
const {
508 return map_->
changeAccess(requiredAccess, prohibitedAccess, *
this, flags);
515 namespace AddressMapImpl {
518 template<
class A,
class T>
526 friend class boost::serialization::access;
529 void serialize(S&,
const unsigned ) {
536 ASSERT_forbid(leftInterval.
isEmpty());
537 ASSERT_always_forbid(rightInterval.
isEmpty());
538 ASSERT_require(leftInterval.
greatest() + 1 == rightInterval.
least());
540 leftSegment.
name() == rightSegment.
name() &&
546 ASSERT_forbid(interval.
isEmpty());
548 Segment right = segment;
554 ASSERT_always_forbid(interval.
isEmpty());
555 ASSERT_always_require(interval.
isContaining(splitPoint));
560 template<
class AddressMap>
565 boost::iterator_range<NodeIterator> nodes_;
573 template<
class AddressMap>
579 return amap.
nodes().end();
583 return amap.
nodes().end();
586 return amap.
nodes().end();
593 if (lb==amap.
nodes().end())
595 minAddr = std::max(*c.
least(), lb->key().least());
599 Iterator lb = amap.
nodes().begin();
600 if (lb!=amap.
nodes().end())
601 minAddr = lb->key().least();
611 template<
class AddressMap>
612 typename AddressMapTraits<AddressMap>::NodeIterator
613 constraintUpperBound(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
bool useAnchor,
615 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
616 if (amap.isEmpty() || c.neverMatches())
617 return amap.nodes().begin();
619 if (useAnchor && c.isAnchored()) {
620 if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
621 return amap.nodes().begin();
622 Iterator ub = amap.findPrior(c.anchored().greatest());
623 if (ub==amap.nodes().end() || c.anchored().greatest() > ub->key().greatest())
624 return amap.nodes().begin();
625 maxAddr = c.anchored().greatest();
630 Iterator ub = amap.findPrior(*c.greatest());
631 if (ub==amap.nodes().end())
632 return amap.nodes().begin();
633 maxAddr = std::min(ub->key().greatest(), *c.greatest());
637 maxAddr = amap.hull().greatest();
638 return amap.nodes().end();
642 template<
class AddressMap>
644 isSatisfied(
const typename AddressMap::Node &node,
const AddressMapConstraints<AddressMap> &c) {
648 const Segment &segment = node.value();
649 if (!segment.isAccessible(c.required(), c.prohibited()))
651 if (!boost::contains(segment.name(), c.substr()))
653 if (!c.segmentPredicates().apply(
true,
typename SegmentPredicate<Address, Value>::Args(node.key(), node.value())))
659 template<
class AddressMap>
660 MatchedConstraints<AddressMap>
661 matchForward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
663 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
664 MatchedConstraints<AddressMap> retval;
665 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
666 if (c.neverMatches() || amap.isEmpty())
671 Iterator begin = constraintLowerBound(amap, c,
true, minAddr );
672 if (begin == amap.nodes().end())
677 Iterator end = constraintUpperBound(amap, c,
false, maxAddr );
678 if (end==amap.nodes().begin())
682 while (begin!=end && !isSatisfied(*begin, c)) {
689 minAddr = std::max(minAddr, begin->key().least());
692 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
693 Address addr = minAddr;
694 Iterator iter = begin;
695 size_t nElmtsFound = 0;
696 for (; iter!=end; ++iter) {
698 if (c.isSingleSegment())
700 if ((flags & MATCH_CONTIGUOUS)!=0 && addr+1 != iter->key().least())
702 if (!isSatisfied(*iter, c)) {
703 if ((flags & MATCH_WHOLE)!=0)
708 size_t nElmtsHere = iter->key().greatest() + 1 - std::max(minAddr, iter->key().least());
709 if (nElmtsFound + nElmtsHere >= c.limit()) {
710 size_t nNeed = c.limit() - nElmtsFound;
711 addr = std::max(minAddr, iter->key().least()) + nNeed - 1;
715 addr = iter->key().greatest();
716 nElmtsFound += nElmtsHere;
719 maxAddr = std::min(maxAddr, addr);
724 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
729 template<
class AddressMap>
730 MatchedConstraints<AddressMap>
731 matchBackward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
733 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
734 MatchedConstraints<AddressMap> retval;
735 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
736 if (c.neverMatches() || amap.isEmpty())
741 Iterator begin = constraintLowerBound(amap, c,
false, minAddr );
742 if (begin == amap.nodes().end())
747 Iterator end = constraintUpperBound(amap, c,
true, maxAddr );
748 if (end==amap.nodes().begin())
753 Iterator prev = end; --prev;
754 if (isSatisfied(*prev, c)) {
755 maxAddr = std::min(maxAddr, prev->key().greatest());
767 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
768 Address addr = maxAddr;
770 size_t nElmtsFound = 0;
771 for (; iter!=begin; --iter) {
772 Iterator prev = iter; --prev;
774 if (c.isSingleSegment())
776 if ((flags & MATCH_CONTIGUOUS)!=0 && prev->key().greatest()+1 != addr)
778 if (!isSatisfied(*prev, c)) {
779 if ((flags & MATCH_WHOLE)!=0)
784 size_t nElmtsHere = std::min(maxAddr, prev->key().greatest()) - prev->key().least() + 1;
785 if (nElmtsFound + nElmtsHere >= c.limit()) {
786 size_t nNeed = c.limit() - nElmtsFound;
787 addr = std::min(maxAddr, prev->key().greatest()) - nNeed + 1;
791 addr = prev->key().least();
792 nElmtsFound += nElmtsHere;
795 minAddr = std::max(minAddr, addr);
800 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
805 template<
class AddressMap>
806 MatchedConstraints<AddressMap>
807 matchConstraints(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
808 if ((flags & MATCH_BACKWARD) != 0)
809 return matchBackward(amap, c, flags);
810 return matchForward(amap, c, flags);
970 template<
class A,
class T = boost::u
int8_t>
971 class AddressMap:
public IntervalMap<Interval<A>, AddressSegment<A, T>, AddressMapImpl::SegmentMergePolicy<A, T> > {
988 friend class boost::serialization::access;
991 void serialize(S &s,
const unsigned ) {
992 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
1016 BOOST_FOREACH (Segment &segment, this->
values()) {
1018 buffer->copyOnWrite(
true);
1282 BOOST_FOREACH (
const Node &node,
nodes()) {
1284 const Segment &segment = node.
value();
1285 if (segment.
buffer()==NULL) {
1286 throw std::runtime_error(
"AddressMap null buffer for interval [" +
1287 boost::lexical_cast<std::string>(interval.
least()) +
1288 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"]");
1291 if (bufAvail < interval.
size()) {
1292 throw std::runtime_error(
"AddressMap segment at [" + boost::lexical_cast<std::string>(interval.
least()) +
1293 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"] points to only " +
1294 boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?
" value":
" values") +
1295 " but the interval size is " + boost::lexical_cast<std::string>(interval.
size()));
1314 boost::iterator_range<ConstSegmentIterator>
segments()
const {
return this->
values(); }
1336 boost::iterator_range<ConstSegmentIterator>
1338 using namespace AddressMapImpl;
1339 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1340 flags |= MATCH_CONTIGUOUS;
1341 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1342 return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1345 boost::iterator_range<SegmentIterator>
1347 using namespace AddressMapImpl;
1348 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1349 flags |= MATCH_CONTIGUOUS;
1350 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1351 return boost::iterator_range<SegmentIterator>(m.nodes_);
1384 boost::iterator_range<ConstNodeIterator>
1386 using namespace AddressMapImpl;
1387 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1388 flags |= MATCH_CONTIGUOUS;
1389 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1393 boost::iterator_range<NodeIterator>
1395 using namespace AddressMapImpl;
1396 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1397 flags |= MATCH_CONTIGUOUS;
1398 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1442 using namespace AddressMapImpl;
1443 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1444 flags |= MATCH_CONTIGUOUS;
1445 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c.
limit(1), flags);
1456 using namespace AddressMapImpl;
1457 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1458 flags |= MATCH_CONTIGUOUS;
1459 return matchConstraints(*
this, c, flags).interval_;
1472 return next(c, flags);
1511 MatchFlags flags=0)
const {
1513 ASSERT_forbid2(nValues == 0,
"cannot determine if this is an overflow or intentional");
1515 if (restriction.isEmpty())
1518 if (0 == (flags & MATCH_BACKWARD)) {
1519 Address minAddr = restriction.least();
1520 while (minAddr <= restriction.greatest()) {
1524 minAddr = alignUp(interval.
least(), alignment);
1525 Address maxAddr = minAddr + (nValues-1);
1526 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1527 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1538 ASSERT_require((flags & MATCH_BACKWARD) != 0);
1539 Address maxAddr = restriction.greatest();
1540 while (maxAddr >= restriction.least()) {
1544 Address minAddr = alignDown(interval.
greatest() - (nValues-1), alignment);
1545 maxAddr = minAddr + (nValues-1);
1546 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1547 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1553 maxAddr = interval.
least() - 1;
1588 template<
typename Functor>
1590 using namespace AddressMapImpl;
1591 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1592 BOOST_FOREACH (
const Node &node, m.nodes_) {
1594 if (!functor(*
this, part))
1599 template<
typename Functor>
1601 using namespace AddressMapImpl;
1602 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1603 BOOST_FOREACH (
const Node &node, m.nodes_) {
1605 if (!functor(*
this, part))
1611 traverse<Visitor>(visitor, c, flags);
1614 traverse<Visitor>(visitor, c, flags);
1658 using namespace AddressMapImpl;
1659 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be read");
1660 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1661 flags |= MATCH_CONTIGUOUS;
1662 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1664 BOOST_FOREACH (
const Node &node, m.nodes_) {
1666 ASSERT_forbid(part.
isEmpty());
1667 Address bufferOffset = part.
least() - node.
key().least() + node.
value().offset();
1668 Address nValues = node.
value().buffer()->read(buf, bufferOffset, part.
size());
1669 if (nValues != part.
size()) {
1671 ASSERT_not_reachable(
"something is wrong with the memory map");
1719 using namespace AddressMapImpl;
1720 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be written");
1721 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1722 flags |= MATCH_CONTIGUOUS;
1723 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
prohibit(Access::IMMUTABLE), flags);
1725 BOOST_FOREACH (Node &node, m.nodes_) {
1726 Segment &segment = node.
value();
1728 ASSERT_forbid(part.
isEmpty());
1730 ASSERT_not_null(buffer);
1732 if (buffer->copyOnWrite()) {
1734 ASSERT_not_null(newBuffer);
1735 for (NodeIterator iter=this->
lowerBound(node.
key().least()); iter!=
nodes().end(); ++iter) {
1736 if (iter->value().buffer() == buffer)
1737 iter->value().buffer(newBuffer);
1742 Address bufferOffset = part.
least() - node.
key().least() + segment.
offset();
1743 Address nValues = buffer->write(buf, bufferOffset, part.
size());
1744 if (nValues != part.
size()) {
1746 ASSERT_not_reachable(
"something is wrong with the memory map");
1773 using namespace AddressMapImpl;
1775 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1776 flags |= MATCH_NONCONTIGUOUS;
1777 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1778 BOOST_FOREACH (
const Node &node, m.nodes_) {
1779 if (isSatisfied(node, c))
1780 toErase.
insert(node.
key() & m.interval_);
1783 this->
erase(interval);
1800 using namespace AddressMapImpl;
1801 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1802 flags |= MATCH_NONCONTIGUOUS;
1804 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1805 BOOST_FOREACH (
const Node &node, m.nodes_) {
1806 if (isSatisfied(node, c))
1807 toKeep.
insert(node.
key() & m.interval_);
1811 this->
erase(interval);
1834 MatchFlags flags=0) {
1835 using namespace AddressMapImpl;
1836 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1837 flags |= MATCH_NONCONTIGUOUS;
1838 typedef std::pair<Sawyer::Container::Interval<Address>, Segment> ISPair;
1839 std::vector<ISPair> newSegments;
1840 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1841 BOOST_FOREACH (Node &node, m.nodes_) {
1842 Segment &segment = node.
value();
1843 if (isSatisfied(node, c)) {
1844 unsigned newAccess = (segment.
accessibility() | requiredAccess) & ~prohibitedAccess;
1846 if (toChange == node.
key()) {
1849 Segment newSegment(segment);
1852 newSegments.push_back(ISPair(toChange, newSegment));
1856 BOOST_FOREACH (
const ISPair &pair, newSegments)
1857 this->
insert(pair.first, pair.second);
1862 static Address alignUp(Address x, Address alignment) {
1863 return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1866 static Address alignDown(Address x, Address alignment) {
1867 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.
bool isContaining(const Interval &other) const
Containment predicate.
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 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.
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.