[gtk/im-context-work] composetable: Add api to check tables



commit 9ebf3fac7372eef75ebe7c283ab9dbdbb9f28412
Author: Matthias Clasen <mclasen redhat com>
Date:   Mon Feb 1 19:40:22 2021 -0500

    composetable: Add api to check tables
    
    This copies the check_table code from gtkimcontextsimple.c,
    in order to have an api for tests.

 gtk/gtkcomposetable.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++
 gtk/gtkcomposetable.h |  21 ++++++----
 2 files changed, 117 insertions(+), 7 deletions(-)
---
diff --git a/gtk/gtkcomposetable.c b/gtk/gtkcomposetable.c
index cbce3f4efa..d485f8ba1d 100644
--- a/gtk/gtkcomposetable.c
+++ b/gtk/gtkcomposetable.c
@@ -853,3 +853,106 @@ gtk_compose_table_list_add_file (GSList     *compose_tables,
   gtk_compose_table_save_cache (compose_table);
   return g_slist_prepend (compose_tables, compose_table);
 }
+
+static int
+compare_seq (const void *key, const void *value)
+{
+  int i = 0;
+  const guint16 *keysyms = key;
+  const guint16 *seq = value;
+
+  while (keysyms[i])
+    {
+      if (keysyms[i] < seq[i])
+        return -1;
+      else if (keysyms[i] > seq[i])
+        return 1;
+
+      i++;
+    }
+
+  return 0;
+}
+
+/*
+ * gtk_compose_table_check:
+ * @table: the table to check
+ * @compose_buffer: the key vals to match
+ * @n_compose: number of non-zero key vals in @compose_buffer
+ * @compose_finish: (out): return location for whether there may be longer matches
+ * @compose_match: (out): return location for whether there is a match
+ * @output_value: (out): return location for the match value
+ *
+ * Looks for matches for a key sequence in @table.
+ *
+ * Returns: %TRUE if there were any matches, %FALSE otherwise
+ */
+gboolean
+gtk_compose_table_check (const GtkComposeTable *table,
+                         guint16               *compose_buffer,
+                         int                    n_compose,
+                         gboolean              *compose_finish,
+                         gboolean              *compose_match,
+                         gunichar              *output_value)
+{
+  int row_stride = table->max_seq_len + 2;
+  guint16 *seq;
+
+  *compose_finish = FALSE;
+  *compose_match = FALSE;
+  *output_value = 0;
+
+  /* Will never match, if the sequence in the compose buffer is longer
+   * than the sequences in the table.  Further, compare_seq (key, val)
+   * will overrun val if key is longer than val.
+   */
+  if (n_compose > table->max_seq_len)
+    return FALSE;
+
+  seq = bsearch (compose_buffer,
+                 table->data, table->n_seqs,
+                 sizeof (guint16) * row_stride,
+                 compare_seq);
+
+  if (seq)
+    {
+      guint16 *prev_seq;
+
+      /* Back up to the first sequence that matches to make sure
+       * we find the exact match if there is one.
+       */
+      while (seq > table->data)
+        {
+          prev_seq = seq - row_stride;
+          if (compare_seq (compose_buffer, prev_seq) != 0)
+            break;
+          seq = prev_seq;
+        }
+
+      if (n_compose == table->max_seq_len ||
+          seq[n_compose] == 0) /* complete sequence */
+        {
+          guint16 *next_seq;
+
+          *output_value = 0x10000 * seq[table->max_seq_len] + seq[table->max_seq_len + 1];
+          *compose_match = TRUE;
+
+          /* We found a tentative match. See if there are any longer
+           * sequences containing this subsequence
+           */
+          next_seq = seq + row_stride;
+          if (next_seq < table->data + row_stride * table->n_seqs)
+            {
+              if (compare_seq (compose_buffer, next_seq) == 0)
+                return TRUE;
+            }
+
+          *compose_finish = TRUE;
+          return TRUE;
+        }
+
+      return TRUE;
+    }
+
+  return FALSE;
+}
diff --git a/gtk/gtkcomposetable.h b/gtk/gtkcomposetable.h
index 885ec6306d..69d82652d1 100644
--- a/gtk/gtkcomposetable.h
+++ b/gtk/gtkcomposetable.h
@@ -42,13 +42,20 @@ struct _GtkComposeTableCompact
   int n_index_stride;
 };
 
-GtkComposeTable * gtk_compose_table_new_with_file (const char    *compose_file);
-GSList *gtk_compose_table_list_add_array          (GSList        *compose_tables,
-                                                   const guint16 *data,
-                                                   int            max_seq_len,
-                                                   int            n_seqs);
-GSList *gtk_compose_table_list_add_file           (GSList        *compose_tables,
-                                                   const char    *compose_file);
+GtkComposeTable * gtk_compose_table_new_with_file  (const char      *compose_file);
+GSList          * gtk_compose_table_list_add_array (GSList          *compose_tables,
+                                                    const guint16   *data,
+                                                    int              max_seq_len,
+                                                    int              n_seqs);
+GSList          * gtk_compose_table_list_add_file  (GSList          *compose_tables,
+                                                    const char      *compose_file);
+
+gboolean          gtk_compose_table_check          (const GtkComposeTable *table,
+                                                    guint16               *compose_buffer,
+                                                    int                    n_compose,
+                                                    gboolean              *compose_finish,
+                                                    gboolean              *compose_match,
+                                                    gunichar              *output_value);
 
 G_END_DECLS
 


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