2019-12-21 18:05:47 +00:00
|
|
|
#include "QtMemoryViewModel.h"
|
2019-12-19 11:58:52 +00:00
|
|
|
|
|
|
|
#include "string_format.h"
|
|
|
|
#include "lexical_cast_ex.h"
|
|
|
|
|
2019-12-21 18:22:22 +00:00
|
|
|
#include <cmath>
|
|
|
|
|
2021-02-11 10:40:08 -05:00
|
|
|
// clang-format off
|
2019-12-21 18:05:47 +00:00
|
|
|
std::vector<CQtMemoryViewModel::UNITINFO> CQtMemoryViewModel::g_units =
|
2021-02-11 10:40:08 -05:00
|
|
|
{
|
|
|
|
{1, 2, &CQtMemoryViewModel::RenderByteUnit, "8-bit Integers"},
|
|
|
|
{4, 8, &CQtMemoryViewModel::RenderWordUnit, "32-bit Integers"},
|
|
|
|
{4, 11, &CQtMemoryViewModel::RenderSingleUnit, "Single Precision Floating Point Numbers"}
|
|
|
|
};
|
|
|
|
// clang-format on
|
2019-12-19 11:58:52 +00:00
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
CQtMemoryViewModel::CQtMemoryViewModel(QObject* parent, getByteProto getByte, int size)
|
2019-12-19 11:58:52 +00:00
|
|
|
: QAbstractTableModel(parent)
|
|
|
|
, m_activeUnit(0)
|
2019-12-21 18:02:39 +00:00
|
|
|
, m_getByte(getByte)
|
2019-12-19 11:58:52 +00:00
|
|
|
, m_size(size)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
int CQtMemoryViewModel::rowCount(const QModelIndex& /*parent*/) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2020-12-25 03:13:53 +00:00
|
|
|
return std::ceil((m_size * 1.f) / m_columnCount);
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
int CQtMemoryViewModel::columnCount(const QModelIndex& /*parent*/) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2020-12-25 03:25:57 +00:00
|
|
|
return (m_columnCount / GetBytesPerUnit()) + 1;
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
QVariant CQtMemoryViewModel::data(const QModelIndex& index, int role) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
if(role == Qt::DisplayRole)
|
|
|
|
{
|
2020-12-25 03:13:53 +00:00
|
|
|
if(index.column() < columnCount() - 1)
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
int offset = (index.column() * g_units[m_activeUnit].bytesPerUnit);
|
2021-01-02 19:15:15 +00:00
|
|
|
int address = index.row() * m_columnCount;
|
2020-12-25 03:13:53 +00:00
|
|
|
return (this->*(g_units[m_activeUnit].renderer))(address + offset).c_str();
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2021-01-02 19:15:15 +00:00
|
|
|
int address = index.row() * m_columnCount;
|
2022-04-01 09:24:09 -04:00
|
|
|
std::string res;
|
2020-12-25 03:13:53 +00:00
|
|
|
for(auto j = 0; j < m_columnCount; j++)
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
if((address + j) >= m_size)
|
2019-12-21 18:22:22 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
res += " ";
|
2019-12-21 18:22:22 +00:00
|
|
|
}
|
2022-04-01 09:24:09 -04:00
|
|
|
else
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
uint8 value = GetByte(address + j);
|
|
|
|
if(value < 0x20 || value > 0x7F)
|
|
|
|
{
|
|
|
|
value = '.';
|
|
|
|
}
|
|
|
|
char valueString[2];
|
|
|
|
valueString[0] = value;
|
|
|
|
valueString[1] = 0x00;
|
|
|
|
res += valueString;
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return res.c_str();
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
return QVariant();
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
QVariant CQtMemoryViewModel::headerData(int section, Qt::Orientation orientation, int role) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
if(role == Qt::DisplayRole)
|
|
|
|
{
|
|
|
|
if(orientation == Qt::Horizontal)
|
|
|
|
{
|
|
|
|
return "";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-12-25 03:13:53 +00:00
|
|
|
auto address = section * m_columnCount;
|
2019-12-19 11:58:52 +00:00
|
|
|
return ("0x" + lexical_cast_hex<std::string>(address, 8)).c_str();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return QAbstractTableModel::headerData(section, orientation, role);
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
void CQtMemoryViewModel::Redraw()
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
emit QAbstractTableModel::beginResetModel();
|
|
|
|
emit QAbstractTableModel::endResetModel();
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
uint8 CQtMemoryViewModel::GetByte(uint32 nAddress) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2019-12-21 18:02:39 +00:00
|
|
|
if(!m_getByte)
|
|
|
|
return 0;
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
return m_getByte(nAddress);
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
std::string CQtMemoryViewModel::RenderByteUnit(uint32 address) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
if(address >= m_size)
|
|
|
|
{
|
|
|
|
return "--";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint8 unitValue = GetByte(address);
|
|
|
|
return string_format("%02X", unitValue);
|
|
|
|
}
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
std::string CQtMemoryViewModel::RenderWordUnit(uint32 address) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
if(address >= m_size)
|
|
|
|
{
|
|
|
|
return "--------";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint32 unitValue =
|
|
|
|
(GetByte(address + 0) << 0) |
|
|
|
|
(GetByte(address + 1) << 8) |
|
|
|
|
(GetByte(address + 2) << 16) |
|
|
|
|
(GetByte(address + 3) << 24);
|
|
|
|
return string_format("%08X", unitValue);
|
|
|
|
}
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
std::string CQtMemoryViewModel::RenderSingleUnit(uint32 address) const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2022-04-01 09:24:09 -04:00
|
|
|
if(address >= m_size)
|
|
|
|
{
|
|
|
|
return "-----------";
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
uint32 unitValue =
|
|
|
|
(GetByte(address + 0) << 0) |
|
|
|
|
(GetByte(address + 1) << 8) |
|
|
|
|
(GetByte(address + 2) << 16) |
|
|
|
|
(GetByte(address + 3) << 24);
|
|
|
|
return string_format("%+04.4e", *reinterpret_cast<const float*>(&unitValue));
|
|
|
|
}
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
unsigned int CQtMemoryViewModel::BytesForCurrentLine() const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2020-12-25 03:13:53 +00:00
|
|
|
return m_columnCount;
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2020-12-25 03:13:53 +00:00
|
|
|
void CQtMemoryViewModel::SetColumnCount(unsigned int count)
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
2020-12-25 03:13:53 +00:00
|
|
|
m_columnCount = count;
|
2019-12-19 11:58:52 +00:00
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
unsigned int CQtMemoryViewModel::CharsPerUnit() const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
return g_units[m_activeUnit].charsPerUnit;
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
void CQtMemoryViewModel::SetActiveUnit(int index)
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
m_activeUnit = index;
|
|
|
|
}
|
|
|
|
|
2019-12-21 18:05:47 +00:00
|
|
|
int CQtMemoryViewModel::GetActiveUnit()
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
return m_activeUnit;
|
|
|
|
}
|
|
|
|
|
2020-12-25 03:13:53 +00:00
|
|
|
unsigned int CQtMemoryViewModel::GetBytesPerUnit() const
|
2019-12-19 11:58:52 +00:00
|
|
|
{
|
|
|
|
return g_units[m_activeUnit].bytesPerUnit;
|
|
|
|
}
|
2019-12-21 18:02:39 +00:00
|
|
|
|
|
|
|
void CQtMemoryViewModel::SetData(getByteProto getByte, int size)
|
|
|
|
{
|
|
|
|
m_getByte = getByte;
|
|
|
|
m_size = size;
|
|
|
|
Redraw();
|
|
|
|
}
|