diff options
author | Vivien Kraus <vivien@planete-kraus.eu> | 2023-03-19 21:20:50 +0100 |
---|---|---|
committer | Vivien Kraus <vivien@planete-kraus.eu> | 2023-03-19 23:25:43 +0100 |
commit | 8d56568d5c75ef606e3aa0a755433e2447aa6901 (patch) | |
tree | 7672f39506f44f9142be0204450102b8c050f6fc | |
parent | 5ba4c8c7ee2db5ead2379a2e9cd99db620eb30eb (diff) |
Add a graphical demo for the cache key computation
-rw-r--r-- | po/POTFILES.in | 1 | ||||
-rw-r--r-- | src/adwaita/Makefile.am | 1 | ||||
-rw-r--r-- | src/adwaita/disfluid-adwaita.h | 2 | ||||
-rw-r--r-- | src/adwaita/disfluid-cache-key-demo.c | 267 | ||||
-rw-r--r-- | src/adwaita/disfluid-window.c | 15 |
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); |