[ghex/expand-search-options] Get autohighlights working with non-exat search types



commit 22cb1da49615dec97b1cb30d190675836c221159
Author: Logan Rathbone <poprocks gmail com>
Date:   Mon Apr 18 22:45:46 2022 -0400

    Get autohighlights working with non-exat search types
    
    - API expansions/refactorings of HexDocument continue.

 src/findreplace.c  | 35 ++++++++++++++++----------
 src/gtkhex.c       | 74 +++++++++++++++++++++++++++++++++++++++---------------
 src/gtkhex.h       |  3 +++
 src/hex-document.c | 66 ++++++++++++++++--------------------------------
 src/hex-document.h | 18 +++++++------
 5 files changed, 111 insertions(+), 85 deletions(-)
---
diff --git a/src/findreplace.c b/src/findreplace.c
index d94257e..2f169da 100644
--- a/src/findreplace.c
+++ b/src/findreplace.c
@@ -221,6 +221,20 @@ gh_is_busy (HexWidget *gh)
                return FALSE;
 }
 
+/* Helper to grab search flags from the GUI */
+static inline HexSearchFlags
+search_flags_from_checkboxes (const FindDialogPrivate *f_priv)
+{
+       HexSearchFlags flags = HEX_SEARCH_NONE;
+
+       if (gtk_check_button_get_active (GTK_CHECK_BUTTON(f_priv->options_regex)))
+               flags |= HEX_SEARCH_REGEX;
+       if (gtk_check_button_get_active (GTK_CHECK_BUTTON(f_priv->options_ignore_case)))
+               flags |= HEX_SEARCH_IGNORE_CASE;
+
+       return flags;
+}
+
 static void
 find_ready_cb (GObject *source_object,
                         GAsyncResult *res,
@@ -232,8 +246,10 @@ find_ready_cb (GObject *source_object,
        PaneDialogPrivate *priv = pane_dialog_get_instance_private (PANE_DIALOG(self));
        FindDialogPrivate *f_priv = find_dialog_get_instance_private (self);
        GtkWindow *parent = GTK_WINDOW(gtk_widget_get_native (GTK_WIDGET(self)));
+       HexSearchFlags flags;
 
        find_data = hex_document_find_finish (doc, res);
+       g_object_unref (res);
 
        /* Typically this will be due to a cancellation - could theoretically be
         * an error, but not much we can do to report a search error anyway.
@@ -241,12 +257,12 @@ find_ready_cb (GObject *source_object,
        if (! find_data)
                goto out;
 
-       g_object_unref (res);
+       flags = search_flags_from_checkboxes (f_priv);
 
        if (find_data->found)
        {
                f_priv->found = TRUE;
-               f_priv->last_found_len = find_data->len;
+               f_priv->last_found_len = find_data->found_len;
 
                hex_widget_set_cursor (priv->gh, find_data->offset);
 
@@ -256,8 +272,8 @@ find_ready_cb (GObject *source_object,
                        hex_widget_delete_autohighlight (priv->gh, priv->auto_highlight);
 
                priv->auto_highlight = NULL;
-               priv->auto_highlight = hex_widget_insert_autohighlight (priv->gh,
-                               find_data->what, find_data->len);
+               priv->auto_highlight = hex_widget_insert_autohighlight_full (priv->gh,
+                               find_data->what, find_data->len, flags);
 
                gtk_widget_grab_focus (GTK_WIDGET(priv->gh));
        }
@@ -270,6 +286,7 @@ find_ready_cb (GObject *source_object,
        }
 
 out:
+       // FIXME - g_free find_data ?
        mark_gh_busy (priv->gh, FALSE);
        pane_dialog_update_busy_state (PANE_DIALOG(self));
 }
@@ -288,7 +305,6 @@ find_common (FindDialog *self, enum FindDirection direction,
        gint64 offset;
        char *str;
        HexDocumentFindData *find_data;
-       HexSearchFlags flags;
        
        g_return_if_fail (FIND_IS_DIALOG(self));
 
@@ -309,12 +325,6 @@ find_common (FindDialog *self, enum FindDirection direction,
                return;
        }
 
-       flags = HEX_SEARCH_NONE;
-       if (gtk_check_button_get_active (GTK_CHECK_BUTTON(f_priv->options_regex)))
-               flags |= HEX_SEARCH_REGEX;
-       if (gtk_check_button_get_active (GTK_CHECK_BUTTON(f_priv->options_ignore_case)))
-               flags |= HEX_SEARCH_IGNORE_CASE;
-
        /* Search for requested string */
 
        find_data = g_new0 (HexDocumentFindData, 1);
@@ -322,6 +332,7 @@ find_common (FindDialog *self, enum FindDirection direction,
        find_data->len = str_len;
        find_data->found_msg = found_msg;
        find_data->not_found_msg = not_found_msg;
+       find_data->flags = search_flags_from_checkboxes (f_priv);
        
        g_cancellable_reset (f_priv->cancellable);
 
@@ -333,7 +344,6 @@ find_common (FindDialog *self, enum FindDirection direction,
 
                hex_document_find_forward_full_async (doc,
                                find_data,
-                               flags,
                                f_priv->cancellable,
                                find_ready_cb,
                                self);
@@ -344,7 +354,6 @@ find_common (FindDialog *self, enum FindDirection direction,
 
                hex_document_find_backward_full_async (doc,
                                find_data,
-                               flags,
                                f_priv->cancellable,
                                find_ready_cb,
                                self);
diff --git a/src/gtkhex.c b/src/gtkhex.c
index c34b57f..ade8e8b 100644
--- a/src/gtkhex.c
+++ b/src/gtkhex.c
@@ -104,6 +104,8 @@ struct _HexWidgetAutoHighlight
        char *search_string;
        int search_len;
 
+       HexSearchFlags search_flags;
+
        gint64 view_min;
        gint64 view_max;
 
@@ -2044,22 +2046,35 @@ hex_widget_compare_data (HexWidget *self, guchar *cmp, gint64 pos, int len)
 
 static gboolean
 hex_widget_find_limited (HexWidget *self, char *find, int findlen,
-               gint64 lower, gint64 upper, gint64 *found)
+               HexSearchFlags flags, gint64 lower, gint64 upper,
+               gint64 *found, size_t *found_len)
 {
+       gboolean retval = FALSE;
        gint64 pos = lower;
+       HexDocumentFindData *find_data = g_new0 (HexDocumentFindData, 1);
+
+       find_data->what = find;
+       find_data->len = findlen;
+       find_data->flags = flags;
 
        while (pos < upper)
        {
-               if (hex_widget_compare_data (self, (guchar *)find, pos, findlen))
+               if (hex_document_compare_data_full (self->document, find_data, pos)
+                               == 0)
                {
                        *found = pos;
-                       return TRUE;
+                       *found_len = find_data->found_len;
+
+                       retval = TRUE;
+                       goto out;
                }
                pos++;
        }
-       return FALSE;
-}
 
+out:
+       g_free (find_data);
+       return retval;
+}
 
 /* Helper for the autohighlight functions to set a reasonable default
  * view_min () and view_max () value.
@@ -2078,6 +2093,7 @@ hex_widget_update_auto_highlight (HexWidget *self, HexWidgetAutoHighlight *ahl,
        gint64 del_min, del_max;
        gint64 add_min, add_max;
        gint64 foundpos = -1;
+       size_t found_len;
        gint64 prev_min = ahl->view_min;
        gint64 prev_max = ahl->view_max;
        HexWidget_Highlight *cur;
@@ -2119,15 +2135,22 @@ hex_widget_update_auto_highlight (HexWidget *self, HexWidgetAutoHighlight *ahl,
                        hex_widget_delete_highlight (self, ahl, cur);
                        cur = next;
                }
-               else cur = cur->next;
+               else
+                       cur = cur->next;
        }
 
        while (add &&
-                  hex_widget_find_limited (self, ahl->search_string, ahl->search_len,
-                          /* lower */ MAX(add_min, foundpos+1), add_max, &foundpos))
+                  hex_widget_find_limited (self,
+                          ahl->search_string,
+                          ahl->search_len,
+                          ahl->search_flags,
+                          /* lower */ MAX(add_min, foundpos+1),
+                          /* upper */ add_max,
+                          &foundpos,
+                          &found_len))
        {
                hex_widget_insert_highlight (self, ahl,
-                               foundpos, foundpos+(ahl->search_len)-1);
+                               foundpos, foundpos + found_len - 1);
        }
 }
 
@@ -3410,24 +3433,17 @@ hex_widget_set_insert_mode (HexWidget *self, gboolean insert)
                        self->cursor_pos = payload_size - 1;
 }
 
-/**
- * hex_widget_insert_autohighlight:
- * @search: (array length=len) (transfer full): search string to auto-highlight
- * @len: length of the @search string
- *   
- * Insert an auto-highlight of a given search string.
- *
- * Returns: a newly created [struct@Hex.WidgetAutoHighlight] structure
- */
 HexWidgetAutoHighlight *
-hex_widget_insert_autohighlight (HexWidget *self,
+hex_widget_insert_autohighlight_full (HexWidget *self,
                const char *search,
-               int len)
+               int len,
+               HexSearchFlags flags)
 {
        HexWidgetAutoHighlight *new = g_new0 (HexWidgetAutoHighlight, 1);
 
        new->search_string = g_memdup2 (search, len);
        new->search_len = len;
+       new->search_flags = flags;
 
        new->highlights = NULL;
 
@@ -3443,6 +3459,24 @@ hex_widget_insert_autohighlight (HexWidget *self,
        return new;
 }
 
+/**
+ * hex_widget_insert_autohighlight:
+ * @search: (array length=len) (transfer full): search string to auto-highlight
+ * @len: length of the @search string
+ *
+ * Insert an auto-highlight of a given search string.
+ *
+ * Returns: a newly created [struct@Hex.WidgetAutoHighlight] structure
+ */
+HexWidgetAutoHighlight *
+hex_widget_insert_autohighlight (HexWidget *self,
+               const char *search,
+               int len)
+{
+       return hex_widget_insert_autohighlight_full (
+                       self, search, len, HEX_SEARCH_NONE);
+}
+
 /* FIXME - use _free func. */
 /**
  * hex_widget_delete_autohighlight:
diff --git a/src/gtkhex.h b/src/gtkhex.h
index 561fb40..6c2ef3e 100644
--- a/src/gtkhex.h
+++ b/src/gtkhex.h
@@ -101,6 +101,9 @@ void hex_widget_delete_selection (HexWidget *gh);
 
 HexWidgetAutoHighlight *
 hex_widget_insert_autohighlight (HexWidget *gh, const char *search, int len);
+HexWidgetAutoHighlight *
+hex_widget_insert_autohighlight_full (HexWidget *self, const char *search,
+               int len, HexSearchFlags flags);
 void hex_widget_delete_autohighlight (HexWidget *gh, HexWidgetAutoHighlight *ahl);
 
 GtkAdjustment *hex_widget_get_adjustment(HexWidget *gh);
diff --git a/src/hex-document.c b/src/hex-document.c
index a232b6d..92f5e93 100644
--- a/src/hex-document.c
+++ b/src/hex-document.c
@@ -84,20 +84,6 @@ hex_document_find_data_copy (HexDocumentFindData *data)
 G_DEFINE_BOXED_TYPE (HexDocumentFindData, hex_document_find_data,
                hex_document_find_data_copy, g_free)
 
-/* HexDocumentFindFullData (private) */
-typedef struct
-{
-       HexDocumentFindData *find_data;
-       HexSearchFlags flags;
-} HexDocumentFindFullData;
-
-static void
-hex_document_find_full_data_free (HexDocumentFindFullData *full_data)
-{
-       g_clear_pointer (&full_data->find_data, g_free);
-       g_free (full_data);
-}
-
 /* HexChangeData GType Definitions */
 
 /* FIXME - unused and could be unreliable */
@@ -1109,10 +1095,9 @@ hex_document_export_html (HexDocument *doc,
        return TRUE;
 }
 
-static int
+int
 hex_document_compare_data_full (HexDocument *doc,
                HexDocumentFindData *find_data,
-               HexSearchFlags flags,
                gint64 pos)
 {
        char *cp = 0;
@@ -1122,7 +1107,7 @@ hex_document_compare_data_full (HexDocument *doc,
        g_return_val_if_fail (find_data, 0);
        g_return_val_if_fail (find_data->what, 0);
 
-       if (flags & HEX_SEARCH_REGEX)
+       if (find_data->flags & HEX_SEARCH_REGEX)
        {
                GRegex *regex;
                GMatchInfo *match_info;
@@ -1139,7 +1124,7 @@ hex_document_compare_data_full (HexDocument *doc,
                /* match string doesn't have to be UTF-8 */
                regex_compile_flags = G_REGEX_RAW;
 
-               if (flags & HEX_SEARCH_IGNORE_CASE)
+               if (find_data->flags & HEX_SEARCH_IGNORE_CASE)
                        regex_compile_flags |= G_REGEX_CASELESS;
 
                regex = g_regex_new (regex_search_str,
@@ -1168,7 +1153,7 @@ hex_document_compare_data_full (HexDocument *doc,
                        char *word = g_match_info_fetch (match_info, 0);
 
                        g_debug ("Found: %s", word);
-                       find_data->len = strlen (word);
+                       find_data->found_len = strlen (word);
                        g_free (word);
                        retval = 0;
                }
@@ -1183,11 +1168,11 @@ hex_document_compare_data_full (HexDocument *doc,
                        retval = 1;
                }
        }
-       else
+       else    /* non regex */
        {
                cp = hex_buffer_get_data (doc->buffer, pos, find_data->len);
 
-               if (flags & HEX_SEARCH_IGNORE_CASE)
+               if (find_data->flags & HEX_SEARCH_IGNORE_CASE)
                {
                        retval = g_ascii_strncasecmp (cp, find_data->what, find_data->len);
                }
@@ -1195,6 +1180,9 @@ hex_document_compare_data_full (HexDocument *doc,
                {
                        retval = memcmp (cp, find_data->what, find_data->len);
                }
+
+               if (retval == 0)
+                       find_data->found_len = find_data->len;
        }
 out:
        g_clear_error (&local_error);
@@ -1222,9 +1210,9 @@ hex_document_compare_data (HexDocument *doc,
 
        find_data->what = what;
        find_data->len = len;
+       find_data->flags = HEX_SEARCH_NONE;
 
-       retval = hex_document_compare_data_full (doc, find_data, HEX_SEARCH_NONE,
-                       pos);
+       retval = hex_document_compare_data_full (doc, find_data, pos);
        g_free (find_data);
 
        return retval;
@@ -1232,8 +1220,7 @@ hex_document_compare_data (HexDocument *doc,
 
 gboolean
 hex_document_find_forward_full (HexDocument *doc,
-               HexDocumentFindData *find_data,
-               HexSearchFlags flags)
+               HexDocumentFindData *find_data)
 {
        gint64 pos;
        gint64 payload = hex_buffer_get_payload_size (
@@ -1244,7 +1231,7 @@ hex_document_find_forward_full (HexDocument *doc,
        pos = find_data->start;
        while (pos < payload)
        {
-               if (hex_document_compare_data_full (doc, find_data, flags, pos) == 0)
+               if (hex_document_compare_data_full (doc, find_data, pos) == 0)
                {
                        find_data->offset = pos;
                        return TRUE;
@@ -1284,8 +1271,9 @@ hex_document_find_forward (HexDocument *doc, gint64 start, const char *what,
        find_data->start = start;
        find_data->what = what;
        find_data->len = len;
+       find_data->flags = HEX_SEARCH_NONE;
 
-       retval = hex_document_find_forward_full (doc, find_data, HEX_SEARCH_NONE);
+       retval = hex_document_find_forward_full (doc, find_data);
        *offset = find_data->offset;
 
        g_free (find_data);
@@ -1320,12 +1308,11 @@ FUNC_NAME (GTask *task, \
                GCancellable *cancellable) \
 { \
        HexDocument *doc = HEX_DOCUMENT (source_object); \
-       HexDocumentFindFullData *full_data = task_data; \
-       HexDocumentFindData *find_data = full_data->find_data; \
+       HexDocumentFindData *find_data = task_data; \
  \
        g_return_if_fail (find_data); \
  \
-       find_data->found = FUNC_TO_CALL (doc, find_data, full_data->flags); \
+       find_data->found = FUNC_TO_CALL (doc, find_data); \
  \
        g_task_return_pointer (task, find_data, g_free); \
 }
@@ -1353,24 +1340,15 @@ hex_document_find_forward_thread (GTask *task,
 void \
 FUNC_NAME (HexDocument *doc, \
                HexDocumentFindData *find_data, \
-               HexSearchFlags flags, \
                GCancellable *cancellable, \
                GAsyncReadyCallback callback, \
                gpointer user_data) \
 { \
        GTask *task; \
-       HexDocumentFindFullData *full_data = g_new0 (HexDocumentFindFullData, 1); \
- \
-       /* This is kind of gross, but we can't really do any better without \
-        * breaking libgtkhex-4.0 ABI \
-        */ \
-       full_data->find_data = find_data; \
-       full_data->flags = flags; \
  \
        task = g_task_new (doc, cancellable, callback, user_data); \
        g_task_set_return_on_cancel (task, TRUE); \
-       g_task_set_task_data (task, full_data, \
-                       (GDestroyNotify)hex_document_find_full_data_free); \
+       g_task_set_task_data (task, find_data, g_free); \
        g_task_run_in_thread (task, FUNC_TO_CALL); \
 }
 
@@ -1431,8 +1409,7 @@ FIND_ASYNC_TEMPLATE(hex_document_find_forward_async,
 
 gboolean
 hex_document_find_backward_full (HexDocument *doc,
-               HexDocumentFindData *find_data,
-               HexSearchFlags flags)
+               HexDocumentFindData *find_data)
 {
        gint64 pos = find_data->start;
        
@@ -1441,7 +1418,7 @@ hex_document_find_backward_full (HexDocument *doc,
 
        do {
                pos--;
-               if (hex_document_compare_data_full (doc, find_data, flags, pos) == 0) {
+               if (hex_document_compare_data_full (doc, find_data, pos) == 0) {
                        find_data->offset = pos;
                        return TRUE;
                }
@@ -1479,8 +1456,9 @@ hex_document_find_backward (HexDocument *doc, gint64 start, const char *what,
        find_data->start = start;
        find_data->what = what;
        find_data->len = len;
+       find_data->flags = HEX_SEARCH_NONE;
 
-       retval = hex_document_find_backward_full (doc, find_data, HEX_SEARCH_NONE);
+       retval = hex_document_find_backward_full (doc, find_data);
        *offset = find_data->offset;
 
        g_free (find_data);
diff --git a/src/hex-document.h b/src/hex-document.h
index 20ec536..1dc238c 100644
--- a/src/hex-document.h
+++ b/src/hex-document.h
@@ -87,7 +87,9 @@ typedef struct
        gint64 start;
        const char *what;
        size_t len;
+       HexSearchFlags flags;   /* TODO: Since: 4.1 */
        gint64 offset;
+       size_t found_len;               /* TODO: Since: 4.1 */
        const char *found_msg;
        const char *not_found_msg;
 } HexDocumentFindData;
@@ -166,11 +168,12 @@ gboolean  hex_document_undo (HexDocument *doc);
 gboolean       hex_document_redo (HexDocument *doc);
 int                    hex_document_compare_data (HexDocument *doc, const char *what,
                gint64 pos, size_t len);
+int                    hex_document_compare_data_full (HexDocument *doc,
+               HexDocumentFindData *find_data, gint64 pos);
 gboolean       hex_document_find_forward (HexDocument *doc, gint64 start,
                const char *what, size_t len, gint64 *offset);
 gboolean hex_document_find_forward_full (HexDocument *doc,
-               HexDocumentFindData *find_data,
-               HexSearchFlags flags);
+               HexDocumentFindData *find_data);
 
 void   hex_document_find_forward_async (HexDocument *doc, gint64 start,
                const char *what, size_t len, gint64 *offset, const char *found_msg,
@@ -178,22 +181,21 @@ void      hex_document_find_forward_async (HexDocument *doc, gint64 start,
                GAsyncReadyCallback callback, gpointer user_data);
 
 void   hex_document_find_forward_full_async (HexDocument *doc,
-               HexDocumentFindData *find_data, HexSearchFlags flags,
-               GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+               HexDocumentFindData *find_data, GCancellable *cancellable,
+               GAsyncReadyCallback callback, gpointer user_data);
 
 gboolean       hex_document_find_backward (HexDocument *doc, gint64 start,
                const char *what, size_t len, gint64 *offset);
 
 gboolean hex_document_find_backward_full (HexDocument *doc,
-               HexDocumentFindData *find_data,
-               HexSearchFlags flags);
+               HexDocumentFindData *find_data);
 void           hex_document_find_backward_async (HexDocument *doc, gint64 start,
                const char *what, size_t len, gint64 *offset, const char *found_msg,
                const char *not_found_msg, GCancellable *cancellable,
                GAsyncReadyCallback callback, gpointer user_data);
 void   hex_document_find_backward_full_async (HexDocument *doc,
-               HexDocumentFindData *find_data, HexSearchFlags flags,
-               GCancellable *cancellable, GAsyncReadyCallback callback, gpointer user_data);
+               HexDocumentFindData *find_data, GCancellable *cancellable,
+               GAsyncReadyCallback callback, gpointer user_data);
 
 HexDocumentFindData *
 hex_document_find_finish (HexDocument *doc, GAsyncResult *result);


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]