Commit 85dcd851 authored by ck's avatar ck
Browse files

Added 64 bit support to BinEditor.

parent 78d07c6d
...@@ -77,6 +77,7 @@ BinEditor::BinEditor(QWidget *parent) ...@@ -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) ...@@ -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() ...@@ -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() ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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) ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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) ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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: ...@@ -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 { ...@@ -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() ...@@ -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: ...@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment