@@ -1237,6 +1237,244 @@ void CodeNoteModel::EnumeratePointerNotes(ra::ByteAddress nPointerAddress,
12371237 }
12381238}
12391239
1240+ static uint32_t Convert (std::wstring_view svValue, bool isHex) noexcept
1241+ {
1242+ uint32_t nValue = 0 ;
1243+ if (isHex)
1244+ {
1245+ for (const auto c : svValue)
1246+ {
1247+ nValue <<= 4 ;
1248+ if (c <= ' 9' )
1249+ nValue |= (c - ' 0' );
1250+ else if (c <= ' F' )
1251+ nValue |= (c - ' A' + 10 );
1252+ else
1253+ nValue |= (c - ' a' + 10 );
1254+ }
1255+ }
1256+ else
1257+ {
1258+ for (const auto c : svValue)
1259+ {
1260+ nValue *= 10 ;
1261+ nValue += (c - ' 0' );
1262+ }
1263+ }
1264+
1265+ return nValue;
1266+ }
1267+
1268+ static bool ParseRange (std::wstring_view svRange, uint32_t & nLow, uint32_t & nHigh, bool isHex)
1269+ {
1270+ if (svRange.size () > 2 && svRange.at (0 ) == L' 0' && svRange.at (1 ) == L' x' )
1271+ svRange = svRange.substr (2 );
1272+ else if (svRange.size () > 1 && (svRange.at (0 ) == L' h' || svRange.at (0 ) == L' H' ))
1273+ svRange = svRange.substr (1 );
1274+
1275+ size_t nIndex = 0 ;
1276+ while (nIndex < svRange.size () && IsHexDigit (svRange.at (nIndex)))
1277+ ++nIndex;
1278+
1279+ if (nIndex == 0 )
1280+ return false ;
1281+
1282+ const auto svLow = svRange.substr (0 , nIndex);
1283+ std::wstring_view svHigh;
1284+
1285+ while (nIndex < svRange.size () && isspace (svRange.at (nIndex)))
1286+ ++nIndex;
1287+
1288+ if (nIndex < svRange.size ())
1289+ {
1290+ if (svRange.at (nIndex++) != ' -' )
1291+ return false ;
1292+
1293+ const auto nStart = nIndex;
1294+ while (nIndex < svRange.size () && IsHexDigit (svRange.at (nIndex)))
1295+ ++nIndex;
1296+
1297+ if (nIndex == nStart)
1298+ return false ;
1299+
1300+ svHigh = svRange.substr (nStart, nIndex);
1301+ }
1302+
1303+ nLow = Convert (svLow, isHex);
1304+ nHigh = svHigh.empty () ? nLow : Convert (svHigh, isHex);
1305+
1306+ return true ;
1307+ }
1308+
1309+ static bool MatchEnumText (const std::wstring_view svValue, uint32_t nValue, bool isHex)
1310+ {
1311+ const auto nSplit = svValue.find_first_of (L" =:" );
1312+ if (nSplit == std::wstring::npos)
1313+ return false ;
1314+
1315+ const auto svLeft = svValue.substr (0 , nSplit);
1316+
1317+ uint32_t nLow, nHigh;
1318+ if (ParseRange (svLeft, nLow, nHigh, isHex))
1319+ {
1320+ if (nValue >= nLow && nValue <= nHigh)
1321+ return true ;
1322+ }
1323+ else if (svValue.at (nSplit) == L' =' )
1324+ {
1325+ auto svRight = svValue.substr (nSplit + 1 );
1326+ while (!svRight.empty () && isspace (svRight.at (0 )))
1327+ svRight.remove_prefix (1 );
1328+
1329+ if (ParseRange (svRight, nLow, nHigh, isHex))
1330+ {
1331+ if (nValue >= nLow && nValue <= nHigh)
1332+ return true ;
1333+ }
1334+ }
1335+
1336+ return false ;
1337+ }
1338+
1339+ static std::wstring_view GetValues (const std::wstring_view svLine)
1340+ {
1341+ const auto nSplit = svLine.find_first_of (L" =:" );
1342+ if (nSplit == std::wstring::npos)
1343+ return {};
1344+
1345+ size_t nRightBracket = svLine.size () + 1 ;
1346+ const auto nLeftBracket = svLine.find_last_of (L" ([{" , nSplit);
1347+ if (nLeftBracket == std::wstring::npos)
1348+ return svLine;
1349+
1350+ switch (svLine.at (nLeftBracket))
1351+ {
1352+ case ' (' :
1353+ nRightBracket = svLine.find (L' )' , nSplit);
1354+ break ;
1355+ case ' [' :
1356+ nRightBracket = svLine.find (L' ]' , nSplit);
1357+ break ;
1358+ case ' {' :
1359+ nRightBracket = svLine.find (L' }' , nSplit);
1360+ break ;
1361+ }
1362+
1363+ if (nRightBracket == std::wstring::npos)
1364+ return svLine;
1365+
1366+ return svLine.substr (nLeftBracket + 1 , nRightBracket - nLeftBracket - 1 );
1367+ }
1368+
1369+ CodeNoteModel::EnumState CodeNoteModel::DetermineEnumState (const std::wstring_view svNote)
1370+ {
1371+ EnumState nState = EnumState::None;
1372+ size_t nStart = 0 ;
1373+ while (nStart < svNote.size ())
1374+ {
1375+ auto nEnd = svNote.find_first_of (L" \n\r " , nStart);
1376+
1377+ if (nStart != nEnd)
1378+ {
1379+ const auto svLine = svNote.substr (nStart, nEnd - nStart);
1380+ const auto svValues = GetValues (svLine);
1381+ if (!svValues.empty ())
1382+ {
1383+ size_t nFront = 0 ;
1384+ do {
1385+ const auto nComma = svValues.find_first_of (L" ,;" , nFront);
1386+ const auto svValue = (nComma == std::wstring::npos) ? svValues.substr (nFront) : svValues.substr (nFront, nComma - nFront);
1387+
1388+ const auto nSplit = svValue.find_first_of (L" =:" );
1389+ if (nSplit != std::wstring::npos)
1390+ {
1391+ uint32_t nLow, nHigh;
1392+ const auto svLeft = svValue.substr (0 , nSplit);
1393+ if (ParseRange (svLeft, nLow, nHigh, true ))
1394+ {
1395+ if (svLeft.find_first_of (L" ABCDEFabcdefHhx" ) != std::wstring::npos)
1396+ return EnumState::Hex;
1397+
1398+ nState = EnumState::Dec;
1399+ }
1400+ }
1401+
1402+ if (nComma == std::wstring::npos)
1403+ break ;
1404+
1405+ nFront = nComma + 1 ;
1406+ while (nFront < svValues.size () && isspace (svValues.at (nFront)))
1407+ ++nFront;
1408+ } while (nFront < svValues.size ());
1409+ }
1410+ }
1411+
1412+ while (nEnd < svNote.size () && (svNote.at (nEnd) == L' \n ' || svNote.at (nEnd) == L' \r ' ))
1413+ ++nEnd;
1414+
1415+ nStart = nEnd;
1416+ }
1417+
1418+ return nState;
1419+
1420+ }
1421+
1422+ std::wstring_view CodeNoteModel::GetEnumText (uint32_t nValue) const
1423+ {
1424+ if (m_nEnumState == EnumState::None)
1425+ return {};
1426+
1427+ std::wstring_view svNote (m_sNote);
1428+
1429+ if (m_pPointerData != nullptr )
1430+ svNote = svNote.substr (0 , m_pPointerData->HeaderLength );
1431+
1432+ if (m_nEnumState == EnumState::Unknown)
1433+ {
1434+ m_nEnumState = DetermineEnumState (svNote);
1435+ if (m_nEnumState == EnumState::None)
1436+ return {};
1437+ }
1438+
1439+ const bool isHex = (m_nEnumState == EnumState::Hex);
1440+ size_t nStart = 0 ;
1441+ while (nStart < svNote.size ())
1442+ {
1443+ auto nEnd = svNote.find_first_of (L" \n\r " , nStart);
1444+
1445+ if (nStart != nEnd)
1446+ {
1447+ const auto svLine = svNote.substr (nStart, nEnd - nStart);
1448+ const auto svValues = GetValues (svLine);
1449+ if (!svValues.empty ())
1450+ {
1451+ size_t nFront = 0 ;
1452+ do {
1453+ const auto nComma = svValues.find_first_of (L" ,;" , nFront);
1454+ const auto svValue = (nComma == std::wstring::npos) ? svValues.substr (nFront) : svValues.substr (nFront, nComma - nFront);
1455+
1456+ if (MatchEnumText (svValue, nValue, isHex))
1457+ return svValue;
1458+
1459+ if (nComma == std::wstring::npos)
1460+ break ;
1461+
1462+ nFront = nComma + 1 ;
1463+ while (nFront < svValues.size () && isspace (svValues.at (nFront)))
1464+ ++nFront;
1465+ } while (nFront < svValues.size ());
1466+ }
1467+ }
1468+
1469+ while (nEnd < svNote.size () && (svNote.at (nEnd) == L' \n ' || svNote.at (nEnd) == L' \r ' ))
1470+ ++nEnd;
1471+
1472+ nStart = nEnd;
1473+ }
1474+
1475+ return {};
1476+ }
1477+
12401478} // namespace models
12411479} // namespace data
12421480} // namespace ra
0 commit comments