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:
Axel Dörfler 2004-02-29 21:15:31 +00:00
parent 1e88e6620d
commit 0283ecc0cd
4 changed files with 42 additions and 15 deletions

View File

@ -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) {

View File

@ -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; }

View File

@ -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();

View File

@ -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);