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>
30 #if __cplusplus >= 201103L
31 #include <type_traits>
37 template<
class AddressMap>
43 template<
class AddressMap>
51 static const MatchFlags MATCH_BACKWARD = 0x00000001;
52 static const MatchFlags MATCH_CONTIGUOUS = 0x00000002;
53 static const MatchFlags MATCH_NONCONTIGUOUS = 0x00000004;
54 static const MatchFlags MATCH_WHOLE = 0x00000008;
58 template<
class A,
class T>
65 : interval(interval), segment(segment) {}
69 virtual bool operator()(
bool chain,
const Args &) = 0;
79 template<
typename AddressMap>
95 unsigned requiredAccess_;
96 unsigned prohibitedAccess_;
97 std::string nameSubstring_;
102 : map_(map), never_(false), maxSize_(size_t(-1)), singleSegment_(false), requiredAccess_(0), prohibitedAccess_(0) {}
104 #if __cplusplus >= 201103L
107 template<typename U = AddressMap, typename = typename std::enable_if<!std::is_const<U>::value,
void>::type>
120 cc = cc.atOrAfter(*
least());
123 cc = cc.limit(
limit());
125 cc = cc.singleSegment();
133 operator AddressMapConstraints<const AddressMap>()
const {
134 AddressMapConstraints<const AddressMap> cc(map_);
145 cc = cc.atOrAfter(*
least());
148 cc = cc.limit(
limit());
150 cc = cc.singleSegment();
160 void print(std::ostream &out)
const {
161 out <<
"{map=" <<map_;
165 out <<
", least=" <<*least_;
167 out <<
", greatest=" <<*greatest_;
170 AddressInterval a = *anchored_;
179 if (maxSize_ !=
size_t(-1))
180 out <<
", limit=" <<maxSize_;
182 out <<
", single-segment";
183 if (requiredAccess_!=0) {
185 <<((requiredAccess_ & Access::READABLE) ?
"r" :
"")
186 <<((requiredAccess_ & Access::WRITABLE) ?
"w" :
"")
187 <<((requiredAccess_ & Access::EXECUTABLE) ?
"x" :
"")
188 <<((requiredAccess_ & Access::IMMUTABLE) ?
"i" :
"");
189 unsigned other = requiredAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
193 if (prohibitedAccess_!=0) {
195 <<((prohibitedAccess_ & Access::READABLE) ?
"r" :
"")
196 <<((prohibitedAccess_ & Access::WRITABLE) ?
"w" :
"")
197 <<((prohibitedAccess_ & Access::EXECUTABLE) ?
"x" :
"")
198 <<((prohibitedAccess_ & Access::IMMUTABLE) ?
"i" :
"");
199 unsigned other = prohibitedAccess_ & ~(Access::READABLE|Access::WRITABLE|Access::EXECUTABLE|Access::IMMUTABLE);
203 if (!nameSubstring_.empty()) {
205 BOOST_FOREACH (
char ch, nameSubstring_) {
207 case '\a': out <<
"\\a";
break;
208 case '\b': out <<
"\\b";
break;
209 case '\t': out <<
"\\t";
break;
210 case '\n': out <<
"\\n";
break;
211 case '\v': out <<
"\\v";
break;
212 case '\f': out <<
"\\f";
break;
213 case '\r': out <<
"\\r";
break;
214 case '\"': out <<
"\\\"";
break;
215 case '\\': out <<
"\\\\";
break;
221 sprintf(buf,
"\\%03o", (
unsigned)(
unsigned char)ch);
228 if (!segmentPredicates_.isEmpty())
245 retval.requiredAccess_ |= bits;
252 retval.prohibitedAccess_ |= bits;
263 ASSERT_require(nameSubstring_.empty() || nameSubstring_==s);
265 retval.nameSubstring_ = s;
277 retval.never_ =
true;
284 retval.anchored_ = anchored_ ? *anchored_ & AddressInterval(x) : AddressInterval(x);
285 return retval.anchored_->isEmpty() ? retval.
none() : retval;
291 retval.anchored_ = anchored_ ? *anchored_ & x : x;
298 retval.maxSize_ = std::min(maxSize_, x);
299 return 0 == retval.maxSize_ ? retval.
none() : retval;
306 retval.least_ = std::max(*least_, least);
308 retval.least_ =
least;
310 if (greatest_ && *greatest_ < *retval.least_)
319 retval.greatest_ = std::min(*greatest_, greatest);
323 if (least_ && *least_ > *retval.greatest_)
335 return lo<=hi ? within(Sawyer::Container::Interval<Address>::hull(lo, hi)) :
none();
345 return x==boost::integer_traits<Address>::const_max ?
none() :
atOrAfter(x+1);
350 return x==boost::integer_traits<Address>::const_min ?
none() :
atOrBefore(x-1);
356 retval.singleSegment_ =
true;
365 retval.segmentPredicates_.append(p);
371 retval.segmentPredicates_.append(predicates);
380 return requiredAccess_;
385 return prohibitedAccess_;
390 return nameSubstring_;
433 return singleSegment_;
438 return segmentPredicates_;
450 (requiredAccess_ || prohibitedAccess_ || !nameSubstring_.empty() || maxSize_!=size_t(-1) ||
451 singleSegment_ || !segmentPredicates_.isEmpty()));
459 c.greatest_ = greatest_;
460 c.anchored_ = anchored_;
461 c.maxSize_ = maxSize_;
468 boost::iterator_range<typename AddressMapTraits<AddressMap>::NodeIterator>
469 nodes(MatchFlags flags=0)
const {
470 return map_->
nodes(*
this, flags);
473 boost::iterator_range<typename AddressMapTraits<AddressMap>::SegmentIterator>
474 segments(MatchFlags flags=0)
const {
475 return map_->
segments(*
this, flags);
478 Optional<typename AddressMap::Address>
479 next(MatchFlags flags=0)
const {
480 return map_->
next(*
this, flags);
484 available(MatchFlags flags=0)
const {
489 exists(MatchFlags flags=0)
const {
490 return map_->
exists(*
this, flags);
493 typename AddressMapTraits<AddressMap>::NodeIterator
494 findNode(MatchFlags flags=0)
const {
495 return map_->
findNode(*
this, flags);
498 template<
typename Functor>
500 traverse(Functor &functor, MatchFlags flags=0)
const {
501 return map_->
traverse(functor, *
this, flags);
504 traverse(
typename AddressMap::Visitor &visitor, MatchFlags flags=0)
const {
505 return map_->template traverse<typename AddressMap::Visitor>(visitor, *
this, flags);
510 return map_->
read(buf, *
this, flags);
514 read(std::vector<typename AddressMap::Value> &buf ,
515 MatchFlags flags=0)
const {
516 return map_->
read(buf, *
this, flags);
521 return map_->
write(buf, *
this, flags);
525 write(
const std::vector<typename AddressMap::Value> &buf, MatchFlags flags=0) {
526 return map_->
write(buf, *
this, flags);
530 prune(MatchFlags flags=0)
const {
531 return map_->
prune(*
this, flags);
535 keep(MatchFlags flags=0)
const {
536 return map_->
keep(*
this, flags);
540 changeAccess(
unsigned requiredAccess,
unsigned prohibitedAccess, MatchFlags flags=0)
const {
541 return map_->
changeAccess(requiredAccess, prohibitedAccess, *
this, flags);
548 namespace AddressMapImpl {
551 template<
class A,
class T>
559 friend class boost::serialization::access;
562 void serialize(S&,
const unsigned ) {
569 ASSERT_forbid(leftInterval.
isEmpty());
570 ASSERT_always_forbid(rightInterval.
isEmpty());
571 ASSERT_require(leftInterval.
greatest() + 1 == rightInterval.
least());
573 leftSegment.
name() == rightSegment.
name() &&
579 ASSERT_forbid(interval.
isEmpty());
580 ASSERT_require(interval.
contains(splitPoint));
581 Segment right = segment;
587 ASSERT_always_forbid(interval.
isEmpty());
588 ASSERT_always_require(interval.
contains(splitPoint));
593 template<
class AddressMap>
598 boost::iterator_range<NodeIterator> nodes_;
606 template<
class AddressMap>
612 return amap.
nodes().end();
616 return amap.
nodes().end();
619 return amap.
nodes().end();
626 if (lb==amap.
nodes().end())
628 minAddr = std::max(*c.
least(), lb->key().least());
632 Iterator lb = amap.
nodes().begin();
633 if (lb!=amap.
nodes().end())
634 minAddr = lb->key().least();
644 template<
class AddressMap>
645 typename AddressMapTraits<AddressMap>::NodeIterator
646 constraintUpperBound(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c,
bool useAnchor,
648 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
649 if (amap.isEmpty() || c.neverMatches())
650 return amap.nodes().begin();
652 if (useAnchor && c.isAnchored()) {
653 if ((c.least() && *c.least() > c.anchored().least()) || (c.greatest() && *c.greatest() < c.anchored().greatest()))
654 return amap.nodes().begin();
655 Iterator ub = amap.findPrior(c.anchored().greatest());
656 if (ub==amap.nodes().end() || c.anchored().greatest() > ub->key().greatest())
657 return amap.nodes().begin();
658 maxAddr = c.anchored().greatest();
663 Iterator ub = amap.findPrior(*c.greatest());
664 if (ub==amap.nodes().end())
665 return amap.nodes().begin();
666 maxAddr = std::min(ub->key().greatest(), *c.greatest());
670 maxAddr = amap.hull().greatest();
671 return amap.nodes().end();
675 template<
class AddressMap>
677 isSatisfied(
const typename AddressMap::Node &node,
const AddressMapConstraints<AddressMap> &c) {
681 const Segment &segment = node.value();
682 if (!segment.isAccessible(c.required(), c.prohibited()))
684 if (!boost::contains(segment.name(), c.substr()))
686 if (!c.segmentPredicates().apply(
true,
typename SegmentPredicate<Address, Value>::Args(node.key(), node.value())))
692 template<
class AddressMap>
693 MatchedConstraints<AddressMap>
694 matchForward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
696 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
697 MatchedConstraints<AddressMap> retval;
698 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
699 if (c.neverMatches() || amap.isEmpty())
704 Iterator begin = constraintLowerBound(amap, c,
true, minAddr );
705 if (begin == amap.nodes().end())
710 Iterator end = constraintUpperBound(amap, c,
false, maxAddr );
711 if (end==amap.nodes().begin())
715 while (begin!=end && !isSatisfied(*begin, c)) {
722 minAddr = std::max(minAddr, begin->key().least());
725 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
726 Address addr = minAddr;
727 Iterator iter = begin;
728 size_t nElmtsFound = 0;
729 for (; iter!=end; ++iter) {
731 if (c.isSingleSegment())
733 if ((flags & MATCH_CONTIGUOUS)!=0 && addr+1 != iter->key().least())
735 if (!isSatisfied(*iter, c)) {
736 if ((flags & MATCH_WHOLE)!=0)
741 size_t nElmtsHere = iter->key().greatest() + 1 - std::max(minAddr, iter->key().least());
742 if (nElmtsFound + nElmtsHere >= c.limit()) {
743 size_t nNeed = c.limit() - nElmtsFound;
744 addr = std::max(minAddr, iter->key().least()) + nNeed - 1;
748 addr = iter->key().greatest();
749 nElmtsFound += nElmtsHere;
752 maxAddr = std::min(maxAddr, addr);
757 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
762 template<
class AddressMap>
763 MatchedConstraints<AddressMap>
764 matchBackward(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
766 typedef typename AddressMapTraits<AddressMap>::NodeIterator Iterator;
767 MatchedConstraints<AddressMap> retval;
768 retval.nodes_ = boost::iterator_range<Iterator>(amap.nodes().end(), amap.nodes().end());
769 if (c.neverMatches() || amap.isEmpty())
774 Iterator begin = constraintLowerBound(amap, c,
false, minAddr );
775 if (begin == amap.nodes().end())
780 Iterator end = constraintUpperBound(amap, c,
true, maxAddr );
781 if (end==amap.nodes().begin())
786 Iterator prev = end; --prev;
787 if (isSatisfied(*prev, c)) {
788 maxAddr = std::min(maxAddr, prev->key().greatest());
800 if ((flags & MATCH_CONTIGUOUS)!=0 || c.hasNonAddressConstraints()) {
801 Address addr = maxAddr;
803 size_t nElmtsFound = 0;
804 for (; iter!=begin; --iter) {
805 Iterator prev = iter; --prev;
807 if (c.isSingleSegment())
809 if ((flags & MATCH_CONTIGUOUS)!=0 && prev->key().greatest()+1 != addr)
811 if (!isSatisfied(*prev, c)) {
812 if ((flags & MATCH_WHOLE)!=0)
817 size_t nElmtsHere = std::min(maxAddr, prev->key().greatest()) - prev->key().least() + 1;
818 if (nElmtsFound + nElmtsHere >= c.limit()) {
819 size_t nNeed = c.limit() - nElmtsFound;
820 addr = std::min(maxAddr, prev->key().greatest()) - nNeed + 1;
824 addr = prev->key().least();
825 nElmtsFound += nElmtsHere;
828 minAddr = std::max(minAddr, addr);
833 retval.nodes_ = boost::iterator_range<Iterator>(begin, end);
838 template<
class AddressMap>
839 MatchedConstraints<AddressMap>
840 matchConstraints(AddressMap &amap,
const AddressMapConstraints<AddressMap> &c, MatchFlags flags) {
841 if ((flags & MATCH_BACKWARD) != 0)
842 return matchBackward(amap, c, flags);
843 return matchForward(amap, c, flags);
1003 template<
class A,
class T = boost::u
int8_t>
1021 friend class boost::serialization::access;
1024 void serialize(S &s,
const unsigned ) {
1025 s & BOOST_SERIALIZATION_BASE_OBJECT_NVP(Super);
1049 BOOST_FOREACH (Segment &segment, this->
values()) {
1051 buffer->copyOnWrite(
true);
1315 BOOST_FOREACH (
const Node &node,
nodes()) {
1317 const Segment &segment = node.
value();
1318 if (segment.
buffer()==NULL) {
1319 throw std::runtime_error(
"AddressMap null buffer for interval [" +
1320 boost::lexical_cast<std::string>(interval.
least()) +
1321 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"]");
1324 if (bufAvail < interval.
size()) {
1325 throw std::runtime_error(
"AddressMap segment at [" + boost::lexical_cast<std::string>(interval.
least()) +
1326 "," + boost::lexical_cast<std::string>(interval.
greatest()) +
"] points to only " +
1327 boost::lexical_cast<std::string>(bufAvail) + (1==bufAvail?
" value":
" values") +
1328 " but the interval size is " + boost::lexical_cast<std::string>(interval.
size()));
1347 boost::iterator_range<ConstSegmentIterator>
segments()
const {
return this->
values(); }
1369 boost::iterator_range<ConstSegmentIterator>
1371 using namespace AddressMapImpl;
1372 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1373 flags |= MATCH_CONTIGUOUS;
1374 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1375 return boost::iterator_range<ConstSegmentIterator>(m.nodes_.begin(), m.nodes_.end());
1378 boost::iterator_range<SegmentIterator>
1380 using namespace AddressMapImpl;
1381 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1382 flags |= MATCH_CONTIGUOUS;
1383 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1384 return boost::iterator_range<SegmentIterator>(m.nodes_);
1417 boost::iterator_range<ConstNodeIterator>
1419 using namespace AddressMapImpl;
1420 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1421 flags |= MATCH_CONTIGUOUS;
1422 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1426 boost::iterator_range<NodeIterator>
1428 using namespace AddressMapImpl;
1429 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1430 flags |= MATCH_CONTIGUOUS;
1431 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1475 using namespace AddressMapImpl;
1476 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1477 flags |= MATCH_CONTIGUOUS;
1478 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c.
limit(1), flags);
1489 using namespace AddressMapImpl;
1490 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1491 flags |= MATCH_CONTIGUOUS;
1492 return matchConstraints(*
this, c, flags).interval_;
1505 return next(c, flags);
1544 MatchFlags flags=0)
const {
1546 ASSERT_forbid2(nValues == 0,
"cannot determine if this is an overflow or intentional");
1548 if (restriction.isEmpty())
1551 if (0 == (flags & MATCH_BACKWARD)) {
1552 Address minAddr = restriction.least();
1553 while (minAddr <= restriction.greatest()) {
1557 minAddr = alignUp(interval.
least(), alignment);
1558 Address maxAddr = minAddr + (nValues-1);
1559 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1560 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1562 maxAddr <= restriction.greatest()) {
1572 ASSERT_require((flags & MATCH_BACKWARD) != 0);
1573 Address maxAddr = restriction.greatest();
1574 while (maxAddr >= restriction.least()) {
1578 Address minAddr = alignDown(interval.
greatest() - (nValues-1), alignment);
1579 maxAddr = minAddr + (nValues-1);
1580 if ((nValues <= interval.
size() || 0==interval.
size()) &&
1581 minAddr >= interval.
least() && maxAddr >= interval.
least() &&
1583 minAddr >= restriction.least()) {
1588 maxAddr = interval.
least() - 1;
1623 template<
typename Functor>
1625 using namespace AddressMapImpl;
1626 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1627 BOOST_FOREACH (
const Node &node, m.nodes_) {
1629 if (!functor(*
this, part))
1634 template<
typename Functor>
1636 using namespace AddressMapImpl;
1637 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c, flags);
1638 BOOST_FOREACH (
const Node &node, m.nodes_) {
1640 if (!functor(*
this, part))
1646 traverse<Visitor>(visitor, c, flags);
1649 traverse<Visitor>(visitor, c, flags);
1693 using namespace AddressMapImpl;
1694 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be read");
1695 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1696 flags |= MATCH_CONTIGUOUS;
1697 MatchedConstraints<const AddressMap> m = matchConstraints(*
this, c, flags);
1699 BOOST_FOREACH (
const Node &node, m.nodes_) {
1701 ASSERT_forbid(part.
isEmpty());
1702 Address bufferOffset = part.
least() - node.
key().least() + node.
value().offset();
1703 Address nValues = node.
value().buffer()->read(buf, bufferOffset, part.
size());
1704 if (nValues != part.
size()) {
1706 ASSERT_not_reachable(
"something is wrong with the memory map");
1754 using namespace AddressMapImpl;
1755 ASSERT_require2(0 == (flags & MATCH_NONCONTIGUOUS),
"only contiguous addresses can be written");
1756 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1757 flags |= MATCH_CONTIGUOUS;
1758 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
prohibit(Access::IMMUTABLE), flags);
1760 BOOST_FOREACH (Node &node, m.nodes_) {
1761 Segment &segment = node.
value();
1763 ASSERT_forbid(part.
isEmpty());
1765 ASSERT_not_null(buffer);
1767 if (buffer->copyOnWrite()) {
1769 ASSERT_not_null(newBuffer);
1770 for (NodeIterator iter=this->
lowerBound(node.
key().least()); iter!=
nodes().end(); ++iter) {
1771 if (iter->value().buffer() == buffer)
1772 iter->value().buffer(newBuffer);
1777 Address bufferOffset = part.
least() - node.
key().least() + segment.
offset();
1778 Address nValues = buffer->write(buf, bufferOffset, part.
size());
1779 if (nValues != part.
size()) {
1781 ASSERT_not_reachable(
"something is wrong with the memory map");
1808 using namespace AddressMapImpl;
1810 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1811 flags |= MATCH_NONCONTIGUOUS;
1812 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1813 BOOST_FOREACH (
const Node &node, m.nodes_) {
1814 if (isSatisfied(node, c))
1815 toErase.
insert(node.
key() & m.interval_);
1818 this->
erase(interval);
1835 using namespace AddressMapImpl;
1836 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1837 flags |= MATCH_NONCONTIGUOUS;
1839 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1840 BOOST_FOREACH (
const Node &node, m.nodes_) {
1841 if (isSatisfied(node, c))
1842 toKeep.
insert(node.
key() & m.interval_);
1846 this->
erase(interval);
1869 MatchFlags flags=0) {
1870 using namespace AddressMapImpl;
1871 if (0==(flags & (MATCH_CONTIGUOUS|MATCH_NONCONTIGUOUS)))
1872 flags |= MATCH_NONCONTIGUOUS;
1873 typedef std::pair<Sawyer::Container::Interval<Address>, Segment> ISPair;
1874 std::vector<ISPair> newSegments;
1875 MatchedConstraints<AddressMap> m = matchConstraints(*
this, c.
addressConstraints(), flags);
1876 BOOST_FOREACH (Node &node, m.nodes_) {
1877 Segment &segment = node.
value();
1878 if (isSatisfied(node, c)) {
1879 unsigned newAccess = (segment.
accessibility() | requiredAccess) & ~prohibitedAccess;
1881 if (toChange == node.
key()) {
1884 Segment newSegment(segment);
1887 newSegments.push_back(ISPair(toChange, newSegment));
1891 BOOST_FOREACH (
const ISPair &pair, newSegments)
1892 this->
insert(pair.first, pair.second);
1897 static Address alignUp(Address x, Address alignment) {
1898 return alignment>0 && x%alignment!=0 ? ((x+alignment-1)/alignment)*alignment : x;
1901 static Address alignDown(Address x, Address alignment) {
1902 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.