forked from qt-creator/qt-creator
Added 64 bit support to BinEditor.
This commit is contained in:
@@ -77,6 +77,7 @@ BinEditor::BinEditor(QWidget *parent)
|
|||||||
{
|
{
|
||||||
m_ieditor = 0;
|
m_ieditor = 0;
|
||||||
m_inLazyMode = false;
|
m_inLazyMode = false;
|
||||||
|
m_baseAddr = 0;
|
||||||
m_blockSize = 4096;
|
m_blockSize = 4096;
|
||||||
init();
|
init();
|
||||||
m_unmodifiedState = 0;
|
m_unmodifiedState = 0;
|
||||||
@@ -88,7 +89,7 @@ BinEditor::BinEditor(QWidget *parent)
|
|||||||
m_cursorVisible = false;
|
m_cursorVisible = false;
|
||||||
m_caseSensitiveSearch = false;
|
m_caseSensitiveSearch = false;
|
||||||
setFocusPolicy(Qt::WheelFocus);
|
setFocusPolicy(Qt::WheelFocus);
|
||||||
m_addressString = QString(9, QLatin1Char(':'));
|
m_addressString = QString(16 + 3, QLatin1Char(':'));
|
||||||
}
|
}
|
||||||
|
|
||||||
BinEditor::~BinEditor()
|
BinEditor::~BinEditor()
|
||||||
@@ -108,7 +109,7 @@ void BinEditor::init()
|
|||||||
m_numVisibleLines = viewport()->height() / m_lineHeight;
|
m_numVisibleLines = viewport()->height() / m_lineHeight;
|
||||||
m_textWidth = 16 * m_charWidth + m_charWidth;
|
m_textWidth = 16 * m_charWidth + m_charWidth;
|
||||||
int m_numberWidth = fm.width(QChar(QLatin1Char('9')));
|
int m_numberWidth = fm.width(QChar(QLatin1Char('9')));
|
||||||
m_labelWidth = 8 * m_numberWidth + 2 * m_charWidth;
|
m_labelWidth = 16 * m_numberWidth + 4 * m_charWidth;
|
||||||
|
|
||||||
int expectedCharWidth = m_columnWidth / 3;
|
int expectedCharWidth = m_columnWidth / 3;
|
||||||
const char *hex = "0123456789abcdef";
|
const char *hex = "0123456789abcdef";
|
||||||
@@ -129,13 +130,17 @@ void BinEditor::init()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void BinEditor::addLazyData(int block, const QByteArray &data)
|
void BinEditor::addLazyData(quint64 block, const QByteArray &data)
|
||||||
{
|
{
|
||||||
Q_ASSERT(m_inLazyMode);
|
Q_ASSERT(m_inLazyMode);
|
||||||
Q_ASSERT(data.size() == m_blockSize);
|
Q_ASSERT(data.size() == m_blockSize);
|
||||||
m_lazyData.insert(block, data);
|
const quint64 addr = block * m_blockSize;
|
||||||
m_lazyRequests.remove(block);
|
if (addr >= m_baseAddr && addr <= m_baseAddr + m_size - 1) {
|
||||||
viewport()->update();
|
const int translatedBlock = (addr - m_baseAddr) / m_blockSize;
|
||||||
|
m_lazyData.insert(translatedBlock, data);
|
||||||
|
m_lazyRequests.remove(translatedBlock);
|
||||||
|
viewport()->update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
||||||
@@ -148,7 +153,8 @@ bool BinEditor::requestDataAt(int pos, bool synchronous) const
|
|||||||
if (it == m_lazyData.end()) {
|
if (it == m_lazyData.end()) {
|
||||||
if (!m_lazyRequests.contains(block)) {
|
if (!m_lazyRequests.contains(block)) {
|
||||||
m_lazyRequests.insert(block);
|
m_lazyRequests.insert(block);
|
||||||
emit const_cast<BinEditor*>(this)->lazyDataRequested(block, synchronous);
|
emit const_cast<BinEditor*>(this)->
|
||||||
|
lazyDataRequested(m_baseAddr / m_blockSize + block, synchronous);
|
||||||
if (!m_lazyRequests.contains(block))
|
if (!m_lazyRequests.contains(block))
|
||||||
return true; // synchronous data source
|
return true; // synchronous data source
|
||||||
}
|
}
|
||||||
@@ -294,6 +300,7 @@ bool BinEditor::isReadOnly() const
|
|||||||
void BinEditor::setData(const QByteArray &data)
|
void BinEditor::setData(const QByteArray &data)
|
||||||
{
|
{
|
||||||
m_inLazyMode = false;
|
m_inLazyMode = false;
|
||||||
|
m_baseAddr = 0;
|
||||||
m_lazyData.clear();
|
m_lazyData.clear();
|
||||||
m_lazyRequests.clear();
|
m_lazyRequests.clear();
|
||||||
m_data = data;
|
m_data = data;
|
||||||
@@ -325,12 +332,12 @@ bool BinEditor::applyModifications(QByteArray &data) const
|
|||||||
if (data.size() != m_size)
|
if (data.size() != m_size)
|
||||||
return false;
|
return false;
|
||||||
for (QMap<int,QByteArray>::const_iterator it = m_lazyData.begin(); it != m_lazyData.end(); ++it) {
|
for (QMap<int,QByteArray>::const_iterator it = m_lazyData.begin(); it != m_lazyData.end(); ++it) {
|
||||||
::memcpy(data.data() + it.key() * m_blockSize, it->constData(), m_blockSize);
|
::memcpy(data.data() + m_baseAddr + it.key() * m_blockSize, it->constData(), m_blockSize);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
|
void BinEditor::setLazyData(quint64 startAddr, int range, int blockSize)
|
||||||
{
|
{
|
||||||
m_inLazyMode = true;
|
m_inLazyMode = true;
|
||||||
m_blockSize = blockSize;
|
m_blockSize = blockSize;
|
||||||
@@ -339,7 +346,14 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
|
|||||||
m_data.clear();
|
m_data.clear();
|
||||||
m_lazyData.clear();
|
m_lazyData.clear();
|
||||||
m_lazyRequests.clear();
|
m_lazyRequests.clear();
|
||||||
m_size = size;
|
|
||||||
|
// In lazy mode, users can edit data in the range
|
||||||
|
// [startAddr - range/2, startAddr + range/2].
|
||||||
|
m_baseAddr = static_cast<quint64>(range/2) > startAddr
|
||||||
|
? 0 : startAddr - range/2;
|
||||||
|
m_baseAddr = (m_baseAddr / blockSize) * blockSize;
|
||||||
|
m_size = m_baseAddr != 0 && static_cast<quint64>(range) >= -m_baseAddr
|
||||||
|
? -m_baseAddr : range;
|
||||||
|
|
||||||
m_unmodifiedState = 0;
|
m_unmodifiedState = 0;
|
||||||
m_undoStack.clear();
|
m_undoStack.clear();
|
||||||
@@ -347,7 +361,7 @@ void BinEditor::setLazyData(int cursorPosition, int size, int blockSize)
|
|||||||
|
|
||||||
init();
|
init();
|
||||||
|
|
||||||
m_cursorPosition = cursorPosition;
|
m_cursorPosition = startAddr - m_baseAddr;
|
||||||
verticalScrollBar()->setValue(m_cursorPosition / 16);
|
verticalScrollBar()->setValue(m_cursorPosition / 16);
|
||||||
|
|
||||||
emit cursorPositionChanged(m_cursorPosition);
|
emit cursorPositionChanged(m_cursorPosition);
|
||||||
@@ -526,7 +540,8 @@ int BinEditor::dataLastIndexOf(const QByteArray &pattern, int from, bool caseSen
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::FindFlags findFlags)
|
int BinEditor::find(const QByteArray &pattern_arg, int from,
|
||||||
|
QTextDocument::FindFlags findFlags)
|
||||||
{
|
{
|
||||||
if (pattern_arg.isEmpty())
|
if (pattern_arg.isEmpty())
|
||||||
return 0;
|
return 0;
|
||||||
@@ -541,7 +556,7 @@ int BinEditor::find(const QByteArray &pattern_arg, int from, QTextDocument::Find
|
|||||||
bool backwards = (findFlags & QTextDocument::FindBackward);
|
bool backwards = (findFlags & QTextDocument::FindBackward);
|
||||||
int found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch)
|
int found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch)
|
||||||
: dataIndexOf(pattern, from, caseSensitiveSearch);
|
: dataIndexOf(pattern, from, caseSensitiveSearch);
|
||||||
|
|
||||||
int foundHex = -1;
|
int foundHex = -1;
|
||||||
QByteArray hexPattern = calculateHexPattern(pattern_arg);
|
QByteArray hexPattern = calculateHexPattern(pattern_arg);
|
||||||
if (!hexPattern.isEmpty()) {
|
if (!hexPattern.isEmpty()) {
|
||||||
@@ -593,20 +608,21 @@ void BinEditor::drawItems(QPainter *painter, int x, int y, const QString &itemSt
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QString BinEditor::addressString(uint address)
|
QString BinEditor::addressString(quint64 address)
|
||||||
{
|
{
|
||||||
QChar *addressStringData = m_addressString.data();
|
QChar *addressStringData = m_addressString.data();
|
||||||
const char *hex = "0123456789abcdef";
|
const char *hex = "0123456789abcdef";
|
||||||
for (int h = 0; h < 4; ++h) {
|
|
||||||
int shift = 4*(7-h);
|
// Take colons into account.
|
||||||
addressStringData[h] = hex[(address & (0xf<<shift))>>shift];
|
const int indices[16] = {
|
||||||
}
|
0, 1, 2, 3, 5, 6, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18
|
||||||
for (int h = 4; h < 8; ++h) {
|
};
|
||||||
int shift = 4*(7-h);
|
|
||||||
addressStringData[h+1] = hex[(address & (0xf<<shift))>>shift];
|
for (int b = 0; b < 8; ++b) {
|
||||||
|
addressStringData[indices[15 - b*2]] = hex[(address >> (8*b)) & 0xf];
|
||||||
|
addressStringData[indices[14 - b*2]] = hex[(address >> (8*b + 4)) & 0xf];
|
||||||
}
|
}
|
||||||
return m_addressString;
|
return m_addressString;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BinEditor::paintEvent(QPaintEvent *e)
|
void BinEditor::paintEvent(QPaintEvent *e)
|
||||||
@@ -663,7 +679,8 @@ void BinEditor::paintEvent(QPaintEvent *e)
|
|||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|
||||||
painter.drawText(-xoffset, i * m_lineHeight + m_ascent, addressString(((uint) line) * 16));
|
painter.drawText(-xoffset, i * m_lineHeight + m_ascent,
|
||||||
|
addressString(m_baseAddr + ((uint) line) * 16));
|
||||||
|
|
||||||
int cursor = -1;
|
int cursor = -1;
|
||||||
if (line * 16 <= m_cursorPosition && m_cursorPosition < line * 16 + 16)
|
if (line * 16 <= m_cursorPosition && m_cursorPosition < line * 16 + 16)
|
||||||
|
|||||||
@@ -64,9 +64,9 @@ public:
|
|||||||
inline int dataSize() const { return m_size; }
|
inline int dataSize() const { return m_size; }
|
||||||
|
|
||||||
inline bool inLazyMode() const { return m_inLazyMode; }
|
inline bool inLazyMode() const { return m_inLazyMode; }
|
||||||
Q_INVOKABLE void setLazyData(int cursorPosition, int size, int blockSize = 4096);
|
Q_INVOKABLE void setLazyData(quint64 startAddr, int range, int blockSize = 4096);
|
||||||
inline int lazyDataBlockSize() const { return m_blockSize; }
|
inline int lazyDataBlockSize() const { return m_blockSize; }
|
||||||
Q_INVOKABLE void addLazyData(int block, const QByteArray &data);
|
Q_INVOKABLE void addLazyData(quint64 block, const QByteArray &data);
|
||||||
bool applyModifications(QByteArray &data) const;
|
bool applyModifications(QByteArray &data) const;
|
||||||
|
|
||||||
void zoomIn(int range = 1);
|
void zoomIn(int range = 1);
|
||||||
@@ -86,7 +86,8 @@ public:
|
|||||||
void setReadOnly(bool);
|
void setReadOnly(bool);
|
||||||
bool isReadOnly() const;
|
bool isReadOnly() const;
|
||||||
|
|
||||||
int find(const QByteArray &pattern, int from = 0, QTextDocument::FindFlags findFlags = 0);
|
int find(const QByteArray &pattern, int from = 0,
|
||||||
|
QTextDocument::FindFlags findFlags = 0);
|
||||||
|
|
||||||
void selectAll();
|
void selectAll();
|
||||||
void clear();
|
void clear();
|
||||||
@@ -106,7 +107,7 @@ public:
|
|||||||
bool isUndoAvailable() const { return m_undoStack.size(); }
|
bool isUndoAvailable() const { return m_undoStack.size(); }
|
||||||
bool isRedoAvailable() const { return m_redoStack.size(); }
|
bool isRedoAvailable() const { return m_redoStack.size(); }
|
||||||
|
|
||||||
QString addressString(uint address);
|
QString addressString(quint64 address);
|
||||||
|
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
@@ -121,7 +122,7 @@ Q_SIGNALS:
|
|||||||
void copyAvailable(bool);
|
void copyAvailable(bool);
|
||||||
void cursorPositionChanged(int position);
|
void cursorPositionChanged(int position);
|
||||||
|
|
||||||
void lazyDataRequested(int block, bool syncronous);
|
void lazyDataRequested(quint64 block, bool synchronous);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void scrollContentsBy(int dx, int dy);
|
void scrollContentsBy(int dx, int dy);
|
||||||
@@ -169,6 +170,7 @@ private:
|
|||||||
int m_numLines;
|
int m_numLines;
|
||||||
int m_numVisibleLines;
|
int m_numVisibleLines;
|
||||||
|
|
||||||
|
quint64 m_baseAddr;
|
||||||
|
|
||||||
bool m_cursorVisible;
|
bool m_cursorVisible;
|
||||||
int m_cursorPosition;
|
int m_cursorPosition;
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ public:
|
|||||||
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
|
m_mimeType(QLatin1String(BINEditor::Constants::C_BINEDITOR_MIMETYPE))
|
||||||
{
|
{
|
||||||
m_editor = parent;
|
m_editor = parent;
|
||||||
connect(m_editor, SIGNAL(lazyDataRequested(int, bool)), this, SLOT(provideData(int)));
|
connect(m_editor, SIGNAL(lazyDataRequested(quint64, bool)), this, SLOT(provideData(quint64)));
|
||||||
}
|
}
|
||||||
~BinEditorFile() {}
|
~BinEditorFile() {}
|
||||||
|
|
||||||
@@ -162,7 +162,8 @@ public:
|
|||||||
file.write(data);
|
file.write(data);
|
||||||
file.close();
|
file.close();
|
||||||
m_editor->setModified(false);
|
m_editor->setModified(false);
|
||||||
m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
|
m_editor->editorInterface()->
|
||||||
|
setDisplayName(QFileInfo(fileName).fileName());
|
||||||
m_fileName = fileName;
|
m_fileName = fileName;
|
||||||
emit changed();
|
emit changed();
|
||||||
return true;
|
return true;
|
||||||
@@ -174,11 +175,13 @@ public:
|
|||||||
QFile file(fileName);
|
QFile file(fileName);
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
m_fileName = fileName;
|
m_fileName = fileName;
|
||||||
if (file.isSequential()) {
|
if (file.isSequential() && file.size() <= INT_MAX) {
|
||||||
m_editor->setData(file.readAll());
|
m_editor->setData(file.readAll());
|
||||||
} else {
|
} else {
|
||||||
m_editor->setLazyData(0, file.size());
|
m_editor->setLazyData(0, qMin(file.size(),
|
||||||
m_editor->editorInterface()->setDisplayName(QFileInfo(fileName).fileName());
|
static_cast<qint64>(INT_MAX)));
|
||||||
|
m_editor->editorInterface()->
|
||||||
|
setDisplayName(QFileInfo(fileName).fileName());
|
||||||
}
|
}
|
||||||
file.close();
|
file.close();
|
||||||
return true;
|
return true;
|
||||||
@@ -187,7 +190,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void provideData(int block) {
|
void provideData(quint64 block) {
|
||||||
QFile file(m_fileName);
|
QFile file(m_fileName);
|
||||||
if (file.open(QIODevice::ReadOnly)) {
|
if (file.open(QIODevice::ReadOnly)) {
|
||||||
int blockSize = m_editor->lazyDataBlockSize();
|
int blockSize = m_editor->lazyDataBlockSize();
|
||||||
|
|||||||
@@ -57,7 +57,7 @@ namespace Internal {
|
|||||||
//
|
//
|
||||||
///////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\class MemoryViewAgent
|
\class MemoryViewAgent
|
||||||
|
|
||||||
Objects form this class are created in response to user actions in
|
Objects form this class are created in response to user actions in
|
||||||
@@ -84,30 +84,30 @@ MemoryViewAgent::~MemoryViewAgent()
|
|||||||
m_editor->deleteLater();
|
m_editor->deleteLater();
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryViewAgent::init(quint64 addr)
|
void MemoryViewAgent::init(quint64 addr)
|
||||||
{
|
{
|
||||||
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
Core::EditorManager *editorManager = Core::EditorManager::instance();
|
||||||
QString titlePattern = tr("Memory $");
|
QString titlePattern = tr("Memory $");
|
||||||
m_editor = editorManager->openEditorWithContents(
|
m_editor = editorManager->openEditorWithContents(
|
||||||
Core::Constants::K_DEFAULT_BINARY_EDITOR,
|
Core::Constants::K_DEFAULT_BINARY_EDITOR,
|
||||||
&titlePattern);
|
&titlePattern);
|
||||||
connect(m_editor->widget(), SIGNAL(lazyDataRequested(int,bool)),
|
connect(m_editor->widget(), SIGNAL(lazyDataRequested(quint64,bool)),
|
||||||
this, SLOT(fetchLazyData(int,bool)));
|
this, SLOT(fetchLazyData(quint64,bool)));
|
||||||
editorManager->activateEditor(m_editor);
|
editorManager->activateEditor(m_editor);
|
||||||
QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
|
QMetaObject::invokeMethod(m_editor->widget(), "setLazyData",
|
||||||
Q_ARG(int, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
|
Q_ARG(quint64, addr), Q_ARG(int, INT_MAX), Q_ARG(int, BinBlockSize));
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryViewAgent::fetchLazyData(int block, bool sync)
|
void MemoryViewAgent::fetchLazyData(quint64 block, bool sync)
|
||||||
{
|
{
|
||||||
Q_UNUSED(sync); // FIXME: needed support for incremental searching
|
Q_UNUSED(sync); // FIXME: needed support for incremental searching
|
||||||
m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
|
m_engine->fetchMemory(this, BinBlockSize * block, BinBlockSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
|
void MemoryViewAgent::addLazyData(quint64 addr, const QByteArray &ba)
|
||||||
{
|
{
|
||||||
QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
|
QMetaObject::invokeMethod(m_editor->widget(), "addLazyData",
|
||||||
Q_ARG(int, addr / BinBlockSize), Q_ARG(QByteArray, ba));
|
Q_ARG(quint64, addr / BinBlockSize), Q_ARG(QByteArray, ba));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public slots:
|
|||||||
// Called from Engine
|
// Called from Engine
|
||||||
void addLazyData(quint64 addr, const QByteArray &data);
|
void addLazyData(quint64 addr, const QByteArray &data);
|
||||||
// Called from Editor
|
// Called from Editor
|
||||||
void fetchLazyData(int block, bool sync);
|
void fetchLazyData(quint64 block, bool sync);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void init(quint64 startaddr);
|
void init(quint64 startaddr);
|
||||||
|
|||||||
Reference in New Issue
Block a user