Implemented case insensitive search. It's now available in hex mode as well.
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@6822 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
1e88e6620d
commit
0283ecc0cd
@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <ctype.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
|
|
||||||
@ -114,6 +115,19 @@ dump_block(const uint8 *buffer, int size, const char *prefix)
|
|||||||
#endif // TRACE_DATA_EDITOR
|
#endif // TRACE_DATA_EDITOR
|
||||||
|
|
||||||
|
|
||||||
|
static int
|
||||||
|
CompareCaseInsensitive(const uint8 *a, const uint8 *b, size_t size)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < size; i++) {
|
||||||
|
uint8 diff = tolower(a[i]) - tolower(b[i]);
|
||||||
|
if (diff)
|
||||||
|
return diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
CompareOffsets(const off_t *a, const off_t *b)
|
CompareOffsets(const off_t *a, const off_t *b)
|
||||||
{
|
{
|
||||||
@ -969,7 +983,8 @@ DataEditor::GetViewBuffer(const uint8 **_buffer)
|
|||||||
|
|
||||||
off_t
|
off_t
|
||||||
DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
||||||
bool cyclic, BMessenger progressMonitor, volatile bool *stop)
|
bool caseInsensitive, bool cyclic, BMessenger progressMonitor,
|
||||||
|
volatile bool *stop)
|
||||||
{
|
{
|
||||||
if (data == NULL || dataSize == 0)
|
if (data == NULL || dataSize == 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
@ -979,6 +994,13 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
|||||||
|
|
||||||
BAutolock locker(this);
|
BAutolock locker(this);
|
||||||
|
|
||||||
|
typedef int (*compare_func)(const uint8 *a, const uint8 *b, size_t size);
|
||||||
|
compare_func compareFunc;
|
||||||
|
if (caseInsensitive)
|
||||||
|
compareFunc = CompareCaseInsensitive;
|
||||||
|
else
|
||||||
|
compareFunc = (compare_func)memcmp;
|
||||||
|
|
||||||
bool savedIsReadOnly = fIsReadOnly;
|
bool savedIsReadOnly = fIsReadOnly;
|
||||||
fIsReadOnly = true;
|
fIsReadOnly = true;
|
||||||
off_t savedOffset = fViewOffset;
|
off_t savedOffset = fViewOffset;
|
||||||
@ -1027,7 +1049,7 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
|||||||
if (matchLastOffset != 0) {
|
if (matchLastOffset != 0) {
|
||||||
// we had a partial match in the previous block, let's
|
// we had a partial match in the previous block, let's
|
||||||
// check if it is a whole match
|
// check if it is a whole match
|
||||||
if (!memcmp(fView, data + matchLastOffset, dataSize - matchLastOffset)) {
|
if (!compareFunc(fView, data + matchLastOffset, dataSize - matchLastOffset)) {
|
||||||
matchLastOffset = 0;
|
matchLastOffset = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -1040,7 +1062,7 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
|||||||
if (position + i + dataSize > fSize)
|
if (position + i + dataSize > fSize)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (fView[i] == data[0]) {
|
if (!compareFunc(fView + i, data, 1)) {
|
||||||
// one byte matches, compare the rest
|
// one byte matches, compare the rest
|
||||||
size_t size = dataSize - 1;
|
size_t size = dataSize - 1;
|
||||||
size_t offset = i + 1;
|
size_t offset = i + 1;
|
||||||
@ -1048,7 +1070,7 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
|||||||
if (offset + size > fRealViewSize)
|
if (offset + size > fRealViewSize)
|
||||||
size = fRealViewSize - offset;
|
size = fRealViewSize - offset;
|
||||||
|
|
||||||
if (size == 0 || !memcmp(fView + offset, data + 1, size)) {
|
if (size == 0 || !compareFunc(fView + offset, data + 1, size)) {
|
||||||
foundAt = position + i;
|
foundAt = position + i;
|
||||||
|
|
||||||
if (size != dataSize - 1) {
|
if (size != dataSize - 1) {
|
||||||
|
@ -73,7 +73,8 @@ class DataEditor : public BLocker {
|
|||||||
void StopWatching(BMessenger target);
|
void StopWatching(BMessenger target);
|
||||||
void StopWatching(BHandler *handler, BLooper *looper = NULL);
|
void StopWatching(BHandler *handler, BLooper *looper = NULL);
|
||||||
|
|
||||||
off_t Find(off_t startPosition, const uint8 *data, size_t dataSize, bool cyclic,
|
off_t Find(off_t startPosition, const uint8 *data, size_t dataSize,
|
||||||
|
bool caseInsensitive, bool cyclic,
|
||||||
BMessenger progressMessenger, volatile bool *stop = NULL);
|
BMessenger progressMessenger, volatile bool *stop = NULL);
|
||||||
|
|
||||||
BFile &File() { return fFile; }
|
BFile &File() { return fFile; }
|
||||||
|
@ -414,8 +414,10 @@ FindWindow::FindWindow(BRect rect, BMessage &previous, BMessenger &target)
|
|||||||
NULL, B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
NULL, B_FOLLOW_LEFT | B_FOLLOW_BOTTOM);
|
||||||
fCaseCheckBox->ResizeToPreferred();
|
fCaseCheckBox->ResizeToPreferred();
|
||||||
fCaseCheckBox->MoveTo(5, button->Frame().top - 5 - fCaseCheckBox->Bounds().Height());
|
fCaseCheckBox->MoveTo(5, button->Frame().top - 5 - fCaseCheckBox->Bounds().Height());
|
||||||
fCaseCheckBox->SetValue(previous.FindBool("case_sensitive"));
|
bool caseSensitive;
|
||||||
fCaseCheckBox->SetEnabled(mode == kAsciiMode);
|
if (previous.FindBool("case_sensitive", &caseSensitive) != B_OK)
|
||||||
|
caseSensitive = true;
|
||||||
|
fCaseCheckBox->SetValue(caseSensitive);
|
||||||
view->AddChild(fCaseCheckBox);
|
view->AddChild(fCaseCheckBox);
|
||||||
|
|
||||||
// and now those inbetween
|
// and now those inbetween
|
||||||
@ -459,10 +461,7 @@ FindWindow::MessageReceived(BMessage *message)
|
|||||||
if (message->FindInt8("mode", &mode) != B_OK)
|
if (message->FindInt8("mode", &mode) != B_OK)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (fTextView->SetMode((find_mode)mode) == B_OK) {
|
if (fTextView->SetMode((find_mode)mode) != B_OK) {
|
||||||
// the "case sensitive" check box is only for ASCII mode
|
|
||||||
fCaseCheckBox->SetEnabled(mode == kAsciiMode);
|
|
||||||
} else {
|
|
||||||
// activate other item
|
// activate other item
|
||||||
fMenu->ItemAt(mode == kAsciiMode ? 1 : 0)->SetMarked(true);
|
fMenu->ItemAt(mode == kAsciiMode ? 1 : 0)->SetMarked(true);
|
||||||
beep();
|
beep();
|
||||||
|
@ -169,7 +169,8 @@ class EditorLooper : public BLooper {
|
|||||||
virtual void MessageReceived(BMessage *message);
|
virtual void MessageReceived(BMessage *message);
|
||||||
|
|
||||||
bool FindIsRunning() const { return !fQuitFind; }
|
bool FindIsRunning() const { return !fQuitFind; }
|
||||||
void Find(off_t startAt, const uint8 *data, size_t dataSize, BMessenger progressMonitor);
|
void Find(off_t startAt, const uint8 *data, size_t dataSize,
|
||||||
|
bool caseInsensitive, BMessenger progressMonitor);
|
||||||
void QuitFind();
|
void QuitFind();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -932,10 +933,12 @@ EditorLooper::MessageReceived(BMessage *message)
|
|||||||
off_t startAt = 0;
|
off_t startAt = 0;
|
||||||
message->FindInt64("start", &startAt);
|
message->FindInt64("start", &startAt);
|
||||||
|
|
||||||
|
bool caseInsensitive = !message->FindBool("case_sensitive");
|
||||||
|
|
||||||
ssize_t dataSize;
|
ssize_t dataSize;
|
||||||
const uint8 *data;
|
const uint8 *data;
|
||||||
if (message->FindData("data", B_RAW_TYPE, (const void **)&data, &dataSize) == B_OK)
|
if (message->FindData("data", B_RAW_TYPE, (const void **)&data, &dataSize) == B_OK)
|
||||||
Find(startAt, data, dataSize, progressMonitor);
|
Find(startAt, data, dataSize, caseInsensitive, progressMonitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -946,7 +949,8 @@ EditorLooper::MessageReceived(BMessage *message)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
EditorLooper::Find(off_t startAt, const uint8 *data, size_t dataSize, BMessenger progressMonitor)
|
EditorLooper::Find(off_t startAt, const uint8 *data, size_t dataSize,
|
||||||
|
bool caseInsensitive, BMessenger progressMonitor)
|
||||||
{
|
{
|
||||||
fQuitFind = false;
|
fQuitFind = false;
|
||||||
|
|
||||||
@ -954,7 +958,8 @@ EditorLooper::Find(off_t startAt, const uint8 *data, size_t dataSize, BMessenger
|
|||||||
|
|
||||||
bigtime_t startTime = system_time();
|
bigtime_t startTime = system_time();
|
||||||
|
|
||||||
off_t foundAt = fEditor.Find(startAt, data, dataSize, true, progressMonitor, &fQuitFind);
|
off_t foundAt = fEditor.Find(startAt, data, dataSize, caseInsensitive,
|
||||||
|
true, progressMonitor, &fQuitFind);
|
||||||
if (foundAt >= B_OK) {
|
if (foundAt >= B_OK) {
|
||||||
fEditor.SetViewOffset(foundAt);
|
fEditor.SetViewOffset(foundAt);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user