summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVivien Kraus <vivien@planete-kraus.eu>2023-03-19 21:20:50 +0100
committerVivien Kraus <vivien@planete-kraus.eu>2023-03-19 23:25:43 +0100
commit8d56568d5c75ef606e3aa0a755433e2447aa6901 (patch)
tree7672f39506f44f9142be0204450102b8c050f6fc
parent5ba4c8c7ee2db5ead2379a2e9cd99db620eb30eb (diff)
Add a graphical demo for the cache key computation
-rw-r--r--po/POTFILES.in1
-rw-r--r--src/adwaita/Makefile.am1
-rw-r--r--src/adwaita/disfluid-adwaita.h2
-rw-r--r--src/adwaita/disfluid-cache-key-demo.c267
-rw-r--r--src/adwaita/disfluid-window.c15
5 files changed, 273 insertions, 13 deletions
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 0279f17..482822a 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -3,6 +3,7 @@ desktop/eu.planete_kraus.Disfluid.desktop.in
src/adwaita/disfluid-about.c
src/adwaita/disfluid-application.c
src/adwaita/disfluid-cache-entry.c
+src/adwaita/disfluid-cache-key-demo.c
src/adwaita/disfluid-menus.c
src/adwaita/disfluid-tests-results.c
src/disfluid/run-unit-tests.c
diff --git a/src/adwaita/Makefile.am b/src/adwaita/Makefile.am
index e989970..d8f8f42 100644
--- a/src/adwaita/Makefile.am
+++ b/src/adwaita/Makefile.am
@@ -4,6 +4,7 @@ noinst_LTLIBRARIES += %D%/libdisfluid-adwaita.la
%D%/disfluid-adwaita.h \
%D%/disfluid-about.c \
%D%/disfluid-application.c \
+ %D%/disfluid-cache-key-demo.c \
%D%/disfluid-g-cache-entry.c \
%D%/disfluid-cache-entry.c \
%D%/disfluid-menus.c \
diff --git a/src/adwaita/disfluid-adwaita.h b/src/adwaita/disfluid-adwaita.h
index f0f3f7d..b508884 100644
--- a/src/adwaita/disfluid-adwaita.h
+++ b/src/adwaita/disfluid-adwaita.h
@@ -67,4 +67,6 @@ void disfluid_adw_cache_entry_set_cache_entry (DisfluidAdwCacheEntry *
struct disfluid_cache_entry
*value);
+GtkWidget *disfluid_adw_cache_key_demo (void);
+
#endif /* not H_DISFLUID_ADWAITA_INCLUDED */
diff --git a/src/adwaita/disfluid-cache-key-demo.c b/src/adwaita/disfluid-cache-key-demo.c
new file mode 100644
index 0000000..93ec136
--- /dev/null
+++ b/src/adwaita/disfluid-cache-key-demo.c
@@ -0,0 +1,267 @@
+#include <config.h>
+
+#include "attribute.h"
+#include <disfluid.h>
+#include "disfluid-adwaita.h"
+
+#define STREQ(a, b) (strcmp ((a), (b)) == 0)
+#define STRNEQ(a, b) (! (STREQ (a, b)))
+
+#include <locale.h>
+#include <stdio.h>
+#include <unistd.h>
+#include "gettext.h"
+#include "relocatable.h"
+
+#define _(String) dgettext (PACKAGE, (String))
+#define N_(String) (String)
+
+#include <adwaita.h>
+#include <gtk/gtk.h>
+
+/* *INDENT-OFF* */
+G_BEGIN_DECLS
+/* *INDENT-ON* */
+
+#define DISFLUID_ADW_TYPE_CACHE_KEY_DEMO \
+ disfluid_adw_cache_key_demo_get_type ()
+
+/* *INDENT-OFF* */
+G_DECLARE_FINAL_TYPE (DisfluidAdwCacheKeyDemo,
+ disfluid_adw_cache_key_demo,
+ DISFLUID_ADW, CACHE_KEY_DEMO,
+ AdwPreferencesGroup)
+G_END_DECLS
+/* *INDENT-ON* */
+
+GType disfluid_adw_cache_key_demo_get_type (void);
+
+struct _DisfluidAdwCacheKeyDemo
+{
+ AdwPreferencesGroup parent_instance;
+ AdwEntryRow *scheme_view;
+ GtkTextBuffer *request_buffer;
+ GtkTextBuffer *response_buffer;
+ GtkTextBuffer *output_buffer;
+};
+
+struct _DisfluidAdwCacheKeyDemoClass
+{
+ AdwPreferencesGroupClass parent_instance;
+};
+
+/* *INDENT-OFF* */
+G_DEFINE_TYPE (DisfluidAdwCacheKeyDemo, disfluid_adw_cache_key_demo, ADW_TYPE_PREFERENCES_GROUP)
+/* *INDENT-ON* */
+
+static void
+disfluid_adw_cache_key_demo_class_init (DisfluidAdwCacheKeyDemoClass * klass)
+{
+ (void) klass;
+}
+
+static inline void
+push_dynamic_text (char **text, size_t *used, size_t *allocated, char c)
+{
+ if (*used == *allocated)
+ {
+ *allocated *= 2;
+ *text = realloc (*text, *allocated);
+ if (*text == NULL)
+ {
+ abort ();
+ }
+ }
+ (*text)[*used] = c;
+ *used += 1;
+}
+
+static inline char *
+get_text_buffer_data (GtkTextBuffer * buffer)
+{
+ GtkTextIter iter_start = { 0 };
+ GtkTextIter iter_end = { 0 };
+ gtk_text_buffer_get_start_iter (buffer, &iter_start);
+ gtk_text_buffer_get_end_iter (buffer, &iter_end);
+ gchar *raw_text =
+ gtk_text_buffer_get_text (buffer, &iter_start, &iter_end, TRUE);
+ /* raw_text has \n or \r\n line ending, replace them with \r\n. */
+ size_t allocated_size = 1;
+ size_t used_size = 0;
+ char *http_ready = calloc (allocated_size, 1);
+ for (size_t i = 0; i < strlen (raw_text); i++)
+ {
+ if (raw_text[i] != '\r')
+ {
+ if (raw_text[i] == '\n')
+ {
+ push_dynamic_text (&http_ready, &used_size, &allocated_size,
+ '\r');
+ }
+ push_dynamic_text (&http_ready, &used_size, &allocated_size,
+ raw_text[i]);
+ }
+ }
+ push_dynamic_text (&http_ready, &used_size, &allocated_size, '\0');
+ g_free (raw_text);
+ return http_ready;
+}
+
+static inline void
+recompute (DisfluidAdwCacheKeyDemo * self)
+{
+ static const size_t max = 4096;
+ char *key = calloc (max, 1);
+ if (key == NULL)
+ {
+ abort ();
+ }
+ char *scheme =
+ g_strdup (gtk_editable_get_text (GTK_EDITABLE (self->scheme_view)));
+ char *request_header = get_text_buffer_data (self->request_buffer);
+ char *response_header = get_text_buffer_data (self->response_buffer);
+ int error =
+ disfluid_compute_cache_key (scheme, request_header, response_header, max,
+ key);
+ switch (error)
+ {
+ case 0:
+ gtk_text_buffer_set_text (self->output_buffer, key, strlen (key));
+ break;
+ case -1:
+ {
+ const char *error_message =
+ _("Error: there is a problem with your input.");
+ gtk_text_buffer_set_text (self->output_buffer, error_message,
+ strlen (error_message));
+ }
+ break;
+ case -2:
+ {
+ const char *error_message = _("Error: the key would be too large.");
+ gtk_text_buffer_set_text (self->output_buffer, error_message,
+ strlen (error_message));
+ }
+ break;
+ default:
+ {
+ const char *error_message = _("You triggered an unknown error.");
+ gtk_text_buffer_set_text (self->output_buffer, error_message,
+ strlen (error_message));
+ }
+ break;
+ }
+ free (key);
+}
+
+static GtkWidget *
+make_text_view_row (const char *title, const char *default_text,
+ GtkTextBuffer ** buffer, gboolean editable)
+{
+ GtkBox *container = GTK_BOX (g_object_new (GTK_TYPE_BOX,
+ "orientation",
+ GTK_ORIENTATION_VERTICAL,
+ NULL));
+ GtkLabel *title_widget = GTK_LABEL (g_object_new (GTK_TYPE_LABEL,
+ "label", title,
+ "ellipsize",
+ PANGO_ELLIPSIZE_END,
+ "margin-top", 8,
+ "margin-bottom", 8,
+ "margin-start", 8,
+ "margin-end", 8,
+ NULL));
+ *buffer = GTK_TEXT_BUFFER (g_object_new (GTK_TYPE_TEXT_BUFFER,
+ "text", default_text, NULL));
+ GtkTextView *text_view = GTK_TEXT_VIEW (g_object_new (GTK_TYPE_TEXT_VIEW,
+ "monospace", TRUE,
+ "buffer", *buffer,
+ "margin-top", 8,
+ "margin-bottom", 8,
+ "margin-start", 8,
+ "margin-end", 8,
+ "editable", editable,
+ NULL));
+ gtk_box_append (container, GTK_WIDGET (title_widget));
+ gtk_box_append (container, GTK_WIDGET (text_view));
+ AdwPreferencesRow *ret =
+ ADW_PREFERENCES_ROW (g_object_new (ADW_TYPE_PREFERENCES_ROW,
+ "title", title,
+ "activatable", FALSE,
+ "selectable", FALSE,
+ "child", container,
+ NULL));
+ return GTK_WIDGET (ret);
+}
+
+static inline void
+change_scheme (GtkEditable * editable, void *user_data)
+{
+ (void) editable;
+ DisfluidAdwCacheKeyDemo *context = user_data;
+ recompute (context);
+}
+
+static inline void
+change_text_buffer (GtkTextBuffer * ptr, void *user_data)
+{
+ (void) ptr;
+ DisfluidAdwCacheKeyDemo *context = user_data;
+ recompute (context);
+}
+
+static void
+disfluid_adw_cache_key_demo_init (DisfluidAdwCacheKeyDemo * self)
+{
+ g_object_set (G_OBJECT (self),
+ "title", _("Cache key demo"),
+ "description",
+ _("See how disfluid indexes a request/response pair."), NULL);
+ /* TRANSLATORS: Make sure the HTTP/1.1 example stays valid (the CR
+ characters, \r, are not mandatory), but you can translate the URI
+ and host. */
+ const char *request_example = _("\
+GET /example HTTP/1.1\n\
+Host: example.com\n\
+Accept: text/plain\n\
+\n");
+ GtkWidget *request_view =
+ make_text_view_row (_("Request header"), request_example,
+ &(self->request_buffer), TRUE);
+ /* TRANSLATORS: Make sure the HTTP/1.1 example stays valid (the CR
+ characters, \r, are not mandatory), but you can translate the
+ reason phrase and the message. */
+ const char *response_example = _("\
+HTTP/1.1 200 OK\n\
+Content-Type: text/plain\n\
+\n\
+Hi :)\n");
+ GtkWidget *response_view =
+ make_text_view_row (_("Response header"), response_example,
+ &(self->response_buffer), TRUE);
+ GtkWidget *output_view =
+ make_text_view_row (_("Cache key"), "", &(self->output_buffer), FALSE);
+ self->scheme_view =
+ ADW_ENTRY_ROW (g_object_new
+ (ADW_TYPE_ENTRY_ROW, "title", _("HTTP scheme"),
+ "input-purpose", GTK_INPUT_PURPOSE_ALPHA, "activatable",
+ FALSE, "selectable", FALSE, "text", "https", NULL));
+ adw_preferences_group_add (ADW_PREFERENCES_GROUP (self),
+ GTK_WIDGET (self->scheme_view));
+ adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), request_view);
+ adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), response_view);
+ adw_preferences_group_add (ADW_PREFERENCES_GROUP (self), output_view);
+ g_signal_connect (self->scheme_view, "changed", G_CALLBACK (change_scheme),
+ self);
+ g_signal_connect (self->request_buffer, "changed",
+ G_CALLBACK (change_text_buffer), self);
+ g_signal_connect (self->response_buffer, "changed",
+ G_CALLBACK (change_text_buffer), self);
+ recompute (self);
+}
+
+GtkWidget *
+disfluid_adw_cache_key_demo (void)
+{
+ return GTK_WIDGET (g_object_new (DISFLUID_ADW_TYPE_CACHE_KEY_DEMO, NULL));
+}
diff --git a/src/adwaita/disfluid-window.c b/src/adwaita/disfluid-window.c
index ee8fb16..7665349 100644
--- a/src/adwaita/disfluid-window.c
+++ b/src/adwaita/disfluid-window.c
@@ -53,19 +53,8 @@ disfluid_adw_window_init (DisfluidAdwWindow * self)
G_MENU_MODEL (main_menu));
g_object_unref (main_menu);
adw_header_bar_pack_end (ADW_HEADER_BAR (header_bar), menu_button);
- struct disfluid_cache_entry *cache_entry =
- disfluid_cache_entry_alloc (512, 4096, 2097152);
- if (cache_entry == NULL)
- {
- abort ();
- }
- GtkWidget *unique_content =
- g_object_new (DISFLUID_ADW_TYPE_CACHE_ENTRY, NULL);
- disfluid_adw_cache_entry_set_cache_entry (DISFLUID_ADW_CACHE_ENTRY
- (unique_content), cache_entry);
- disfluid_cache_entry_free (cache_entry);
- GtkWidget *main_page = g_object_new (ADW_TYPE_PREFERENCES_PAGE,
- NULL);
+ GtkWidget *unique_content = disfluid_adw_cache_key_demo ();
+ GtkWidget *main_page = g_object_new (ADW_TYPE_PREFERENCES_PAGE, NULL);
adw_preferences_page_add (ADW_PREFERENCES_PAGE (main_page),
ADW_PREFERENCES_GROUP (unique_content));
GtkWidget *content = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);