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 <unistd.h>
#include <ctype.h>
#include <errno.h>
@ -114,6 +115,19 @@ dump_block(const uint8 *buffer, int size, const char *prefix)
#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
CompareOffsets(const off_t *a, const off_t *b)
{
@ -969,7 +983,8 @@ DataEditor::GetViewBuffer(const uint8 **_buffer)
off_t
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)
return B_BAD_VALUE;
@ -979,6 +994,13 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
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;
fIsReadOnly = true;
off_t savedOffset = fViewOffset;
@ -1027,7 +1049,7 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
if (matchLastOffset != 0) {
// we had a partial match in the previous block, let's
// check if it is a whole match
if (!memcmp(fView, data + matchLastOffset, dataSize - matchLastOffset)) {
if (!compareFunc(fView, data + matchLastOffset, dataSize - matchLastOffset)) {
matchLastOffset = 0;
break;
}
@ -1040,7 +1062,7 @@ DataEditor::Find(off_t startPosition, const uint8 *data, size_t dataSize,
if (position + i + dataSize > fSize)
break;
if (fView[i] == data[0]) {
if (!compareFunc(fView + i, data, 1)) {
// one byte matches, compare the rest
size_t size = dataSize - 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)
size = fRealViewSize - offset;
if (size == 0 || !memcmp(fView + offset, data + 1, size)) {
if (size == 0 || !compareFunc(fView + offset, data + 1, size)) {
foundAt = position + i;
if (size != dataSize - 1) {

View File

@ -73,7 +73,8 @@ class DataEditor : public BLocker {
void StopWatching(BMessenger target);
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);
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);
fCaseCheckBox->ResizeToPreferred();
fCaseCheckBox->MoveTo(5, button->Frame().top - 5 - fCaseCheckBox->Bounds().Height());
fCaseCheckBox->SetValue(previous.FindBool("case_sensitive"));
fCaseCheckBox->SetEnabled(mode == kAsciiMode);
bool caseSensitive;
if (previous.FindBool("case_sensitive", &caseSensitive) != B_OK)
caseSensitive = true;
fCaseCheckBox->SetValue(caseSensitive);
view->AddChild(fCaseCheckBox);
// and now those inbetween
@ -459,10 +461,7 @@ FindWindow::MessageReceived(BMessage *message)
if (message->FindInt8("mode", &mode) != B_OK)
break;
if (fTextView->SetMode((find_mode)mode) == B_OK) {
// the "case sensitive" check box is only for ASCII mode
fCaseCheckBox->SetEnabled(mode == kAsciiMode);
} else {
if (fTextView->SetMode((find_mode)mode) != B_OK) {
// activate other item
fMenu->ItemAt(mode == kAsciiMode ? 1 : 0)->SetMarked(true);
beep();

View File

@ -169,7 +169,8 @@ class EditorLooper : public BLooper {
virtual void MessageReceived(BMessage *message);
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();
private:
@ -932,10 +933,12 @@ EditorLooper::MessageReceived(BMessage *message)
off_t startAt = 0;
message->FindInt64("start", &startAt);
bool caseInsensitive = !message->FindBool("case_sensitive");
ssize_t dataSize;
const uint8 *data;
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:
@ -946,7 +949,8 @@ EditorLooper::MessageReceived(BMessage *message)
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;
@ -954,7 +958,8 @@ EditorLooper::Find(off_t startAt, const uint8 *data, size_t dataSize, BMessenger
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) {
fEditor.SetViewOffset(foundAt);