diff --git a/src/apps/diskprobe/DataEditor.cpp b/src/apps/diskprobe/DataEditor.cpp index dabff4f341..07485bf0f2 100644 --- a/src/apps/diskprobe/DataEditor.cpp +++ b/src/apps/diskprobe/DataEditor.cpp @@ -14,6 +14,7 @@ #include #include +#include #include @@ -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) { diff --git a/src/apps/diskprobe/DataEditor.h b/src/apps/diskprobe/DataEditor.h index 8e96263c4e..ce44b82448 100644 --- a/src/apps/diskprobe/DataEditor.h +++ b/src/apps/diskprobe/DataEditor.h @@ -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; } diff --git a/src/apps/diskprobe/FindWindow.cpp b/src/apps/diskprobe/FindWindow.cpp index c6eb9e4c5c..2849f97a66 100644 --- a/src/apps/diskprobe/FindWindow.cpp +++ b/src/apps/diskprobe/FindWindow.cpp @@ -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(); diff --git a/src/apps/diskprobe/ProbeView.cpp b/src/apps/diskprobe/ProbeView.cpp index 6705b81f5b..ced9cf5b51 100644 --- a/src/apps/diskprobe/ProbeView.cpp +++ b/src/apps/diskprobe/ProbeView.cpp @@ -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);