BinEditor: Use 64bit positions in a few more places

This fixes drawing of search hits across the 2^31 boundary.

Searching itself is still buggy.

Change-Id: Icac1722e2693585aa7afe62076ccec9459c18f3a
Reviewed-by: Marcus Tillmanns <marcus.tillmanns@qt.io>
This commit is contained in:
hjk
2024-02-12 12:56:21 +01:00
parent dbc68fe3aa
commit ff85a58ce5
3 changed files with 55 additions and 52 deletions

View File

@@ -79,7 +79,7 @@ public:
m_widget->highlightSearchResults(QByteArray()); m_widget->highlightSearchResults(QByteArray());
} }
int find(const QByteArray &pattern, int pos, FindFlags findFlags, bool *wrapped) qint64 find(const QByteArray &pattern, qint64 pos, FindFlags findFlags, bool *wrapped)
{ {
if (wrapped) if (wrapped)
*wrapped = false; *wrapped = false;
@@ -88,7 +88,7 @@ public:
return pos; return pos;
} }
int res = m_widget->find(pattern, pos, Utils::textDocumentFlagsForFindFlags(findFlags)); qint64 res = m_widget->find(pattern, pos, Utils::textDocumentFlagsForFindFlags(findFlags));
if (res < 0) { if (res < 0) {
pos = (findFlags & FindBackward) ? -1 : 0; pos = (findFlags & FindBackward) ? -1 : 0;
res = m_widget->find(pattern, pos, Utils::textDocumentFlagsForFindFlags(findFlags)); res = m_widget->find(pattern, pos, Utils::textDocumentFlagsForFindFlags(findFlags));
@@ -111,7 +111,7 @@ public:
if (m_contPos == -1) if (m_contPos == -1)
m_contPos = m_incrementalStartPos; m_contPos = m_incrementalStartPos;
bool wrapped; bool wrapped;
int found = find(pattern, m_contPos, findFlags, &wrapped); qint64 found = find(pattern, m_contPos, findFlags, &wrapped);
if (wrapped != m_incrementalWrappedState && (found >= 0)) { if (wrapped != m_incrementalWrappedState && (found >= 0)) {
m_incrementalWrappedState = wrapped; m_incrementalWrappedState = wrapped;
showWrapIndicator(m_widget); showWrapIndicator(m_widget);
@@ -147,7 +147,7 @@ public:
m_contPos = m_widget->selectionStart()-1; m_contPos = m_widget->selectionStart()-1;
} }
bool wrapped; bool wrapped;
int found = find(pattern, m_contPos, findFlags, &wrapped); qint64 found = find(pattern, m_contPos, findFlags, &wrapped);
if (wrapped) if (wrapped)
showWrapIndicator(m_widget); showWrapIndicator(m_widget);
Result result; Result result;

View File

@@ -592,9 +592,9 @@ void BinEditorWidget::updateLines(qint64 fromPosition, qint64 toPosition)
viewport()->update(0, y, viewport()->width(), h); viewport()->update(0, y, viewport()->width(), h);
} }
int BinEditorWidget::dataIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive) const qint64 BinEditorWidget::dataIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive) const
{ {
int trailing = pattern.size(); qint64 trailing = pattern.size();
if (trailing > m_blockSize) if (trailing > m_blockSize)
return -1; return -1;
@@ -603,7 +603,7 @@ int BinEditorWidget::dataIndexOf(const QByteArray &pattern, qint64 from, bool ca
QByteArrayMatcher matcher(pattern); QByteArrayMatcher matcher(pattern);
qint64 block = from / m_blockSize; qint64 block = from / m_blockSize;
const int end = qMin<qint64>(from + SearchStride, m_size); const qint64 end = qMin<qint64>(from + SearchStride, m_size);
while (from < end) { while (from < end) {
if (!requestDataAt(block * m_blockSize)) if (!requestDataAt(block * m_blockSize))
return -1; return -1;
@@ -615,7 +615,7 @@ int BinEditorWidget::dataIndexOf(const QByteArray &pattern, qint64 from, bool ca
if (!caseSensitive) if (!caseSensitive)
buffer = buffer.toLower(); buffer = buffer.toLower();
int pos = matcher.indexIn(buffer, from - (block * m_blockSize) + trailing); qint64 pos = matcher.indexIn(buffer, from - (block * m_blockSize) + trailing);
if (pos >= 0) if (pos >= 0)
return pos + block * m_blockSize - trailing; return pos + block * m_blockSize - trailing;
++block; ++block;
@@ -624,9 +624,9 @@ int BinEditorWidget::dataIndexOf(const QByteArray &pattern, qint64 from, bool ca
return end == m_size ? -1 : -2; return end == m_size ? -1 : -2;
} }
int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive) const qint64 BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive) const
{ {
int trailing = pattern.size(); qint64 trailing = pattern.size();
if (trailing > m_blockSize) if (trailing > m_blockSize)
return -1; return -1;
@@ -635,10 +635,10 @@ int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, boo
if (from == -1) if (from == -1)
from = m_size; from = m_size;
int block = from / m_blockSize; qint64 block = from / m_blockSize;
const int lowerBound = qMax(qint64(0), from - SearchStride); const qint64 lowerBound = qMax<qint64>(0, from - SearchStride);
while (from > lowerBound) { while (from > lowerBound) {
if (!requestDataAt(qint64(block) * m_blockSize)) if (!requestDataAt(block * m_blockSize))
return -1; return -1;
QByteArray data = blockData(block); QByteArray data = blockData(block);
char *b = buffer.data(); char *b = buffer.data();
@@ -648,18 +648,19 @@ int BinEditorWidget::dataLastIndexOf(const QByteArray &pattern, qint64 from, boo
if (!caseSensitive) if (!caseSensitive)
buffer = buffer.toLower(); buffer = buffer.toLower();
int pos = buffer.lastIndexOf(pattern, from - (block * m_blockSize)); qint64 pos = buffer.lastIndexOf(pattern, from - (block * m_blockSize));
if (pos >= 0) if (pos >= 0)
return pos + block * m_blockSize; return pos + block * m_blockSize;
--block; --block;
from = qint64(block) * m_blockSize + (m_blockSize-1) + trailing; from = block * m_blockSize + (m_blockSize-1) + trailing;
} }
return lowerBound == 0 ? -1 : -2; return lowerBound == 0 ? -1 : -2;
} }
int BinEditorWidget::find(const QByteArray &pattern_arg, qint64 from, qint64 BinEditorWidget::find(const QByteArray &pattern_arg,
QTextDocument::FindFlags findFlags) qint64 from,
QTextDocument::FindFlags findFlags)
{ {
if (pattern_arg.isEmpty()) if (pattern_arg.isEmpty())
return 0; return 0;
@@ -672,14 +673,14 @@ int BinEditorWidget::find(const QByteArray &pattern_arg, qint64 from,
pattern = pattern.toLower(); pattern = pattern.toLower();
bool backwards = (findFlags & QTextDocument::FindBackward); bool backwards = (findFlags & QTextDocument::FindBackward);
int found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch) qint64 found = backwards ? dataLastIndexOf(pattern, from, caseSensitiveSearch)
: dataIndexOf(pattern, from, caseSensitiveSearch); : dataIndexOf(pattern, from, caseSensitiveSearch);
int foundHex = -1; qint64 foundHex = -1;
QByteArray hexPattern = calculateHexPattern(pattern_arg); QByteArray hexPattern = calculateHexPattern(pattern_arg);
if (!hexPattern.isEmpty()) { if (!hexPattern.isEmpty()) {
foundHex = backwards ? dataLastIndexOf(hexPattern, from) foundHex = backwards ? dataLastIndexOf(hexPattern, from)
: dataIndexOf(hexPattern, from); : dataIndexOf(hexPattern, from);
} }
qint64 pos = foundHex == -1 || (found >= 0 && (foundHex == -2 || found < foundHex)) qint64 pos = foundHex == -1 || (found >= 0 && (foundHex == -2 || found < foundHex))
@@ -695,15 +696,16 @@ int BinEditorWidget::find(const QByteArray &pattern_arg, qint64 from,
return pos; return pos;
} }
int BinEditorWidget::findPattern(const QByteArray &data, const QByteArray &dataHex, qint64 BinEditorWidget::findPattern(const QByteArray &data, const QByteArray &dataHex,
int from, int offset, int *match) qint64 from, qint64 offset, qint64 *match)
{ {
if (m_searchPattern.isEmpty()) if (m_searchPattern.isEmpty())
return -1; return -1;
int normal = m_searchPattern.isEmpty()
? -1 : data.indexOf(m_searchPattern, from - offset); qint64 normal = m_searchPattern.isEmpty()
int hex = m_searchPatternHex.isEmpty() ? -1 : data.indexOf(m_searchPattern, from - offset);
? -1 : dataHex.indexOf(m_searchPatternHex, from - offset); qint64 hex = m_searchPatternHex.isEmpty()
? -1 : dataHex.indexOf(m_searchPatternHex, from - offset);
if (normal >= 0 && (hex < 0 || normal < hex)) { if (normal >= 0 && (hex < 0 || normal < hex)) {
if (match) if (match)
@@ -787,10 +789,10 @@ void BinEditorWidget::paintEvent(QPaintEvent *e)
painter.fillRect(e->rect() & r, palette().alternateBase()); painter.fillRect(e->rect() & r, palette().alternateBase());
} }
int matchLength = 0; qint64 matchLength = 0;
QByteArray patternData, patternDataHex; QByteArray patternData, patternDataHex;
int patternOffset = qMax(0, topLine*m_bytesPerLine - m_searchPattern.size()); qint64 patternOffset = qMax(0, topLine * m_bytesPerLine - m_searchPattern.size());
if (!m_searchPattern.isEmpty()) { if (!m_searchPattern.isEmpty()) {
patternData = dataMid(patternOffset, m_numVisibleLines * m_bytesPerLine + (topLine*m_bytesPerLine - patternOffset)); patternData = dataMid(patternOffset, m_numVisibleLines * m_bytesPerLine + (topLine*m_bytesPerLine - patternOffset));
patternDataHex = patternData; patternDataHex = patternData;
@@ -798,7 +800,7 @@ void BinEditorWidget::paintEvent(QPaintEvent *e)
patternData = patternData.toLower(); patternData = patternData.toLower();
} }
int foundPatternAt = findPattern(patternData, patternDataHex, patternOffset, patternOffset, &matchLength); qint64 foundPatternAt = findPattern(patternData, patternDataHex, patternOffset, patternOffset, &matchLength);
qint64 selStart, selEnd; qint64 selStart, selEnd;
if (m_cursorPosition >= m_anchorPosition) { if (m_cursorPosition >= m_anchorPosition) {
@@ -817,13 +819,13 @@ void BinEditorWidget::paintEvent(QPaintEvent *e)
painter.setPen(palette().text().color()); painter.setPen(palette().text().color());
const QFontMetrics &fm = painter.fontMetrics(); const QFontMetrics &fm = painter.fontMetrics();
for (int i = 0; i <= m_numVisibleLines; ++i) { for (qint64 i = 0; i <= m_numVisibleLines; ++i) {
qint64 line = topLine + i; qint64 line = topLine + i;
if (line >= m_numLines) if (line >= m_numLines)
break; break;
const quint64 lineAddress = m_baseAddr + line * m_bytesPerLine; const quint64 lineAddress = m_baseAddr + line * m_bytesPerLine;
int y = i * m_lineHeight + m_ascent; qint64 y = i * m_lineHeight + m_ascent;
if (y - m_ascent > e->rect().bottom()) if (y - m_ascent > e->rect().bottom())
break; break;
if (y + m_descent < e->rect().top()) if (y + m_descent < e->rect().top())
@@ -1377,33 +1379,34 @@ void BinEditorWidget::keyPressEvent(QKeyEvent *e)
break; break;
case Qt::Key_PageUp: case Qt::Key_PageUp:
case Qt::Key_PageDown: { case Qt::Key_PageDown: {
int line = qMax(qint64(0), m_cursorPosition / m_bytesPerLine - verticalScrollBar()->value()); qint64 line = qMax(qint64(0), m_cursorPosition / m_bytesPerLine - verticalScrollBar()->value());
verticalScrollBar()->triggerAction(e->key() == Qt::Key_PageUp ? verticalScrollBar()->triggerAction(e->key() == Qt::Key_PageUp ?
QScrollBar::SliderPageStepSub : QScrollBar::SliderPageStepAdd); QScrollBar::SliderPageStepSub : QScrollBar::SliderPageStepAdd);
if (!ctrlPressed) if (!ctrlPressed)
setCursorPosition((verticalScrollBar()->value() + line) * m_bytesPerLine + m_cursorPosition % m_bytesPerLine, moveMode); setCursorPosition((verticalScrollBar()->value() + line) * m_bytesPerLine + m_cursorPosition % m_bytesPerLine, moveMode);
} break; break;
}
case Qt::Key_Home: { case Qt::Key_Home: {
int pos; qint64 pos;
if (ctrlPressed) if (ctrlPressed)
pos = 0; pos = 0;
else else
pos = m_cursorPosition/m_bytesPerLine * m_bytesPerLine; pos = m_cursorPosition / m_bytesPerLine * m_bytesPerLine;
setCursorPosition(pos, moveMode); setCursorPosition(pos, moveMode);
} break; break;
}
case Qt::Key_End: { case Qt::Key_End: {
int pos; qint64 pos;
if (ctrlPressed) if (ctrlPressed)
pos = m_size; pos = m_size;
else else
pos = m_cursorPosition/m_bytesPerLine * m_bytesPerLine + 15; pos = m_cursorPosition / m_bytesPerLine * m_bytesPerLine + 15;
setCursorPosition(pos, moveMode); setCursorPosition(pos, moveMode);
} break; break;
default: }
default: {
if (m_readOnly) if (m_readOnly)
break; break;
{
QString text = e->text(); QString text = e->text();
for (int i = 0; i < text.length(); ++i) { for (int i = 0; i < text.length(); ++i) {
QChar c = text.at(i); QChar c = text.at(i);
@@ -1499,7 +1502,7 @@ void BinEditorWidget::highlightSearchResults(const QByteArray &pattern, QTextDoc
viewport()->update(); viewport()->update();
} }
void BinEditorWidget::changeData(int position, uchar character, bool highNibble) void BinEditorWidget::changeData(qint64 position, uchar character, bool highNibble)
{ {
if (!requestDataAt(position)) if (!requestDataAt(position))
return; return;

View File

@@ -79,7 +79,7 @@ public:
void setReadOnly(bool); void setReadOnly(bool);
bool isReadOnly() const; bool isReadOnly() const;
int find(const QByteArray &pattern, qint64 from = 0, QTextDocument::FindFlags findFlags = {}); qint64 find(const QByteArray &pattern, qint64 from = 0, QTextDocument::FindFlags findFlags = {});
void selectAll(); void selectAll();
void clear(); void clear();
@@ -90,8 +90,8 @@ public:
Core::IEditor *editor() const { return m_ieditor; } Core::IEditor *editor() const { return m_ieditor; }
void setEditor(Core::IEditor *ieditor) { m_ieditor = ieditor; } void setEditor(Core::IEditor *ieditor) { m_ieditor = ieditor; }
int selectionStart() const { return qMin(m_anchorPosition, m_cursorPosition); } qint64 selectionStart() const { return qMin(m_anchorPosition, m_cursorPosition); }
int selectionEnd() const { return qMax(m_anchorPosition, m_cursorPosition); } qint64 selectionEnd() const { return qMax(m_anchorPosition, m_cursorPosition); }
bool event(QEvent*) override; bool event(QEvent*) override;
@@ -146,8 +146,8 @@ private:
QByteArray m_lowerBlock; QByteArray m_lowerBlock;
qint64 m_size = 0; qint64 m_size = 0;
int dataIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive = true) const; qint64 dataIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive = true) const;
int dataLastIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive = true) const; qint64 dataLastIndexOf(const QByteArray &pattern, qint64 from, bool caseSensitive = true) const;
bool requestDataAt(qint64 pos) const; bool requestDataAt(qint64 pos) const;
bool requestOldDataAt(qint64 pos) const; bool requestOldDataAt(qint64 pos) const;
@@ -202,10 +202,10 @@ private:
void ensureCursorVisible(); void ensureCursorVisible();
void setBlinkingCursorEnabled(bool enable); void setBlinkingCursorEnabled(bool enable);
void changeData(int position, uchar character, bool highNibble = false); void changeData(qint64 position, uchar character, bool highNibble = false);
int findPattern(const QByteArray &data, const QByteArray &dataHex, qint64 findPattern(const QByteArray &data, const QByteArray &dataHex,
int from, int offset, int *match); qint64 from, qint64 offset, qint64 *match);
void drawItems(QPainter *painter, int x, int y, const QString &itemString); void drawItems(QPainter *painter, int x, int y, const QString &itemString);
void drawChanges(QPainter *painter, int x, int y, const char *changes); void drawChanges(QPainter *painter, int x, int y, const char *changes);