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 <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) {
|
||||
|
@ -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; }
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user