@@ -1572,8 +1572,10 @@ void TFile::Map(Option_t *opt)
1572
1572
1573
1573
const unsigned char nDigits = std::log10 (fEND ) + 1 ;
1574
1574
1575
+ std::optional<ROOT::Detail::TKeyMapNode> lastNode;
1575
1576
const auto tkeyInfos = WalkTKeys ();
1576
1577
for (const auto &key : tkeyInfos) {
1578
+ lastNode = key;
1577
1579
switch (key.fType ) {
1578
1580
case ROOT::Detail::TKeyMapNode::kError :
1579
1581
Printf (" Address = %" PRIu64 " \t Nbytes = %u\t =====E R R O R=======" , key.fAddr , key.fLen );
@@ -1614,7 +1616,7 @@ void TFile::Map(Option_t *opt)
1614
1616
}
1615
1617
1616
1618
if (!forComp) {
1617
- Int_t datime = tkeyInfos. empty () ? 0 : tkeyInfos. back (). fDatime ;
1619
+ Int_t datime = lastNode ? lastNode-> fDatime : 0 ;
1618
1620
Int_t date, time;
1619
1621
TDatime::GetDateTime (datime, date, time);
1620
1622
Printf (" %d/%06d At:%-*lld N=%-8d %-14s" , date, time, nDigits + 1 , fEND , 1 , " END" );
@@ -1623,94 +1625,108 @@ void TFile::Map(Option_t *opt)
1623
1625
}
1624
1626
}
1625
1627
1626
- std::vector< ROOT::Detail::TKeyMapNode> TFile::WalkTKeys ()
1628
+ ROOT::Detail::TKeyMapIterable TFile::WalkTKeys ()
1627
1629
{
1628
- std::vector<ROOT::Detail::TKeyMapNode> res;
1629
-
1630
- static constexpr int headerSize = 512 ;
1631
-
1632
- std::uint64_t idcur = fBEGIN ;
1633
- const std::uint64_t end = fEND ;
1634
- while (idcur < end) {
1635
- Seek (idcur);
1636
- auto nread = headerSize;
1637
- if (idcur + nread >= end)
1638
- nread = fEND - idcur - 1 ;
1639
-
1640
- char header[headerSize];
1641
- if (ReadBuffer (header, nread)) {
1642
- // ReadBuffer returns kTRUE in case of failure.
1643
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1644
- break ;
1645
- }
1630
+ return ROOT::Detail::TKeyMapIterable (this );
1631
+ }
1646
1632
1647
- char *buffer = header;
1648
- Int_t nbytes;
1649
- frombuf (buffer, &nbytes);
1650
- if (!nbytes) {
1651
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kError });
1652
- break ;
1653
- }
1654
- if (nbytes < 0 ) {
1655
- // free slot
1656
- res.push_back ({idcur, ROOT::Detail::TKeyMapNode::kGap , static_cast <std::uint32_t >(-nbytes)});
1657
- idcur -= nbytes;
1658
- continue ;
1659
- }
1633
+ ROOT::Detail::TKeyMapIterable::TIterator::TIterator (TFile *file, std::uint64_t addr) : fFile(file), fCurAddr(addr)
1634
+ {
1635
+ if (addr == 0 )
1636
+ fCurAddr = fFile ->fBEGIN ;
1637
+ Advance ();
1638
+ }
1660
1639
1661
- auto &node = res.emplace_back (idcur, ROOT::Detail::TKeyMapNode::kKey , nbytes);
1640
+ std::optional<ROOT::Detail::TKeyMapNode> ROOT::Detail::TKeyMapIterable::TIterator::Next ()
1641
+ {
1642
+ static constexpr int headerSize = 512 ;
1662
1643
1663
- frombuf (buffer, &node.fKeyVersion );
1664
- frombuf (buffer, &node.fObjLen );
1665
- frombuf (buffer, &node.fDatime );
1666
- frombuf (buffer, &node.fKeyLen );
1667
- frombuf (buffer, &node.fCycle );
1668
- if (node.fKeyVersion > 1000 ) {
1669
- frombuf (buffer, &node.fSeekKey );
1670
- frombuf (buffer, &node.fSeekPdir );
1644
+ const std::uint64_t idcur = fCurAddr ;
1645
+ const std::uint64_t end = fFile ->fEND ;
1646
+ if (idcur >= end)
1647
+ return std::nullopt;
1648
+
1649
+ fFile ->Seek (idcur);
1650
+ auto nread = headerSize;
1651
+ if (idcur + nread >= end)
1652
+ nread = end - idcur - 1 ;
1653
+
1654
+ char header[headerSize];
1655
+ if (fFile ->ReadBuffer (header, nread)) {
1656
+ // ReadBuffer returns kTRUE in case of failure.
1657
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kError };
1658
+ fCurAddr = end;
1659
+ return node;
1660
+ }
1661
+
1662
+ char *buffer = header;
1663
+ Int_t nbytes;
1664
+ frombuf (buffer, &nbytes);
1665
+ if (!nbytes) {
1666
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kError };
1667
+ fCurAddr = end;
1668
+ return node;
1669
+ }
1670
+
1671
+ if (nbytes < 0 ) {
1672
+ // free slot
1673
+ auto node =
1674
+ ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kGap , static_cast <std::uint32_t >(-nbytes)};
1675
+ fCurAddr -= nbytes;
1676
+ return node;
1677
+ }
1678
+
1679
+ auto node = ROOT::Detail::TKeyMapNode{idcur, ROOT::Detail::TKeyMapNode::kKey , static_cast <std::uint32_t >(nbytes)};
1680
+ frombuf (buffer, &node.fKeyVersion );
1681
+ frombuf (buffer, &node.fObjLen );
1682
+ frombuf (buffer, &node.fDatime );
1683
+ frombuf (buffer, &node.fKeyLen );
1684
+ frombuf (buffer, &node.fCycle );
1685
+ if (node.fKeyVersion > 1000 ) {
1686
+ frombuf (buffer, &node.fSeekKey );
1687
+ frombuf (buffer, &node.fSeekPdir );
1688
+ } else {
1689
+ Int_t skey, sdir;
1690
+ frombuf (buffer, &skey);
1691
+ frombuf (buffer, &sdir);
1692
+ node.fSeekKey = static_cast <Long64_t>(skey);
1693
+ node.fSeekPdir = static_cast <Long64_t>(sdir);
1694
+ }
1695
+
1696
+ const auto readString = [&buffer, &header](bool skipCheck = false ) {
1697
+ char stringLen;
1698
+ char str[256 ];
1699
+ if (!skipCheck && ((buffer - header) >= headerSize)) {
1700
+ stringLen = 0 ;
1671
1701
} else {
1672
- Int_t skey, sdir;
1673
- frombuf (buffer, &skey);
1674
- frombuf (buffer, &sdir);
1675
- node.fSeekKey = static_cast <Long64_t>(skey);
1676
- node.fSeekPdir = static_cast <Long64_t>(sdir);
1677
- }
1678
-
1679
- const auto readString = [&buffer, &header] (bool skipCheck = false ) {
1680
- char stringLen;
1681
- char str[256 ];
1682
- if (!skipCheck && ((buffer - header) >= headerSize)) {
1702
+ frombuf (buffer, &stringLen);
1703
+ if (stringLen < 0 )
1683
1704
stringLen = 0 ;
1684
- } else {
1685
- frombuf (buffer, &stringLen);
1686
- if (stringLen < 0 )
1687
- stringLen = 0 ;
1688
- else if ((buffer - header) + stringLen > headerSize)
1689
- stringLen = headerSize - (buffer - header);
1690
- }
1691
- for (int i = 0 ; i < stringLen; ++i)
1692
- frombuf (buffer, &str[i]);
1693
- str[static_cast <int >(stringLen)] = 0 ;
1705
+ else if ((buffer - header) + stringLen > headerSize)
1706
+ stringLen = headerSize - (buffer - header);
1707
+ }
1708
+ for (int i = 0 ; i < stringLen; ++i)
1709
+ frombuf (buffer, &str[i]);
1710
+ str[static_cast <int >(stringLen)] = 0 ;
1694
1711
1695
- return std::string (str, stringLen);
1696
- };
1712
+ return std::string (str, stringLen);
1713
+ };
1697
1714
1698
- node.fClassName = readString (true );
1715
+ node.fClassName = readString (true );
1699
1716
1700
- if (idcur == static_cast <std::uint64_t >(fSeekFree ))
1701
- node.fClassName = " FreeSegments" ;
1702
- else if (idcur == static_cast <std::uint64_t >(fSeekInfo ))
1703
- node.fClassName = " StreamerInfo" ;
1704
- else if (idcur == static_cast <std::uint64_t >(fSeekKeys ))
1705
- node.fClassName = " KeysList" ;
1717
+ if (idcur == static_cast <std::uint64_t >(fFile -> fSeekFree ))
1718
+ node.fClassName = " FreeSegments" ;
1719
+ else if (idcur == static_cast <std::uint64_t >(fFile -> fSeekInfo ))
1720
+ node.fClassName = " StreamerInfo" ;
1721
+ else if (idcur == static_cast <std::uint64_t >(fFile -> fSeekKeys ))
1722
+ node.fClassName = " KeysList" ;
1706
1723
1707
- node.fKeyName = readString ();
1708
- node.fKeyTitle = readString ();
1724
+ node.fKeyName = readString ();
1725
+ node.fKeyTitle = readString ();
1709
1726
1710
- idcur += nbytes;
1711
- }
1727
+ fCurAddr += nbytes;
1712
1728
1713
- return res ;
1729
+ return node ;
1714
1730
}
1715
1731
1716
1732
// //////////////////////////////////////////////////////////////////////////////
0 commit comments