From Didier Gautheron:
authorAnders Broman <anders.broman@ericsson.com>
Wed, 19 Aug 2009 18:37:13 +0000 (18:37 -0000)
committerAnders Broman <anders.broman@ericsson.com>
Wed, 19 Aug 2009 18:37:13 +0000 (18:37 -0000)
Part 2
Extracted from optimizations patch http://wiki.wireshark.org/Development/Optimization
Optimize expert info.
Slightly changed by me.

svn path=/trunk/; revision=29478

epan/libwireshark.def
epan/strutil.c
epan/strutil.h
gtk/Makefile.common
gtk/expert_comp_dlg.c
gtk/expert_comp_table.c
gtk/expert_comp_table.h
gtk/expert_dlg.c

index bf3fecc12ce6453b59d5e87257963e9fcebb8566..59aa9863bbe2a7dd798311be5ab1207d92e97328 100644 (file)
@@ -364,6 +364,8 @@ epan_dissect_run
 epan_get_version
 epan_init
 epan_strcasestr
+escape_string
+escape_string_len
 ethertype
 ether_to_str
 ex_opt_add
index 1b952443b99af23e47f01149b757880c35a6c9ad..1bf2272f7d774faceea00eadf9ff4dd0124c818c 100644 (file)
@@ -959,3 +959,68 @@ string_or_null(const char *string)
     return string;
   return "[NULL]";
 }
+
+int 
+escape_string_len(const char *string)
+{
+       const char *p;
+       gchar c;
+       int repr_len;
+
+       repr_len = 0;
+       for (p = string; (c = *p) != '\0'; p++) {
+               /* Backslashes and double-quotes must
+                * be escaped */
+               if (c == '\\' || c == '"') {
+                       repr_len += 2;
+               }
+               /* Values that can't nicely be represented
+                * in ASCII need to be escaped. */
+               else if (!isprint((unsigned char)c)) {
+                       /* c --> \xNN */
+                       repr_len += 4;
+               }
+               /* Other characters are just passed through. */
+               else {
+                       repr_len++;
+               }
+       }
+       return repr_len + 2;    /* string plus leading and trailing quotes */
+}
+
+char * 
+escape_string(char *buf, const char *string)
+{
+  const gchar *p;
+  gchar c;
+  char *bufp;
+  char hex[3];
+
+  bufp = buf;
+  *bufp++ = '"';
+  for (p = string; (c = *p) != '\0'; p++) {
+       /* Backslashes and double-quotes must
+        * be escaped. */
+       if (c == '\\' || c == '"') {
+               *bufp++ = '\\';
+               *bufp++ = c;
+       }
+       /* Values that can't nicely be represented
+        * in ASCII need to be escaped. */
+       else if (!isprint((unsigned char)c)) {
+               /* c --> \xNN */
+               g_snprintf(hex,sizeof(hex), "%02x", (unsigned char) c);
+               *bufp++ = '\\';
+               *bufp++ = 'x';
+               *bufp++ = hex[0];
+               *bufp++ = hex[1];
+       }
+       /* Other characters are just passed through. */
+       else {
+               *bufp++ = c;
+       }
+  }
+  *bufp++ = '"';
+  *bufp = '\0';
+  return buf;
+}
index 4ee9b2202576fc09880d16bc440ac1df8ace55cd..4305bf09b1d868fe91b018f2d48917ec04ff6032 100644 (file)
@@ -222,4 +222,7 @@ char * epan_strcasestr(const char *haystack, const char *needle);
  */
 const char * string_or_null(const char *string);
 
+int escape_string_len(const char *string);
+char * escape_string(char *dst, const char *string);
+
 #endif /* __STRUTIL_H__ */
index e0f31df051b37469102270209ee742dbf7d37fd7..ff18f524f3eae085c633ccb6159122e6df497a3a 100644 (file)
@@ -230,6 +230,7 @@ noinst_HEADERS = \
        drag_and_drop.h \
        expert_comp_dlg.h       \
        expert_comp_table.h     \
+       expert_dlg.h    \
        export_object.h \
        file_dlg.h      \
        fileset_dlg.h   \
index 63ae32943d69d0a00eb77512b259dc2f6b9a921c..1de1f5deae2670095340dc3cb5e9468d515f71b5 100644 (file)
@@ -71,6 +71,8 @@ typedef struct _expert_comp_dlg_t {
     guint32 error_events;
 } expert_comp_dlg_t;
 
+static GtkWidget  *expert_comp_dlg_w = NULL;
+
 static void
 error_set_title(expert_comp_dlg_t *ss)
 {
@@ -123,7 +125,6 @@ error_packet(void *pss, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const v
 {
     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)pss;
     const expert_info_t *error_pkt=prv;
-    gchar *buf = NULL; /* set to NULL to prevent warnings */
 
     /* if return value is 0 then no error */
     if(error_pkt==NULL){
@@ -135,56 +136,64 @@ error_packet(void *pss, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const v
         ss->disp_events++;
         ss->error_events++;
         init_error_table_row(&ss->error_table, error_pkt);
-        add_error_table_data(&ss->error_table, error_pkt);
-        buf = g_strdup_printf("Errors: %u (%u)", ss->error_table.num_procs, ss->error_events);
-        gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
         break;
     case PI_WARN:
         ss->disp_events++;
         ss->warn_events++;
         init_error_table_row(&ss->warn_table, error_pkt);
-        add_error_table_data(&ss->warn_table, error_pkt);
-        buf = g_strdup_printf("Warnings: %u (%u)", ss->warn_table.num_procs, ss->warn_events);
-        gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
         break;
     case PI_NOTE:
         ss->disp_events++;
         ss->note_events++;
         init_error_table_row(&ss->note_table, error_pkt);
-        add_error_table_data(&ss->note_table, error_pkt);
-        buf = g_strdup_printf("Notes: %u (%u)", ss->note_table.num_procs, ss->note_events);
-        gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
         break;
     case PI_CHAT:
         ss->disp_events++;
         ss->chat_events++;
         init_error_table_row(&ss->chat_table, error_pkt);
-        add_error_table_data(&ss->chat_table, error_pkt);
-        buf = g_strdup_printf("Chats: %u (%u)", ss->chat_table.num_procs, ss->chat_events);
-        gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
         break;
     default:
         return 0; /* Don't draw */
     }
+    return 1; /* Draw */
+}
+
+static void
+expert_comp_draw(void *data)
+{
+    gchar *buf = NULL;
+
+    expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
+
+    buf = g_strdup_printf("Errors: %u (%u)", ss->error_table.num_procs, ss->error_events);
+    gtk_label_set_text( GTK_LABEL(ss->error_label), buf);
+    g_free(buf);
+
+    buf = g_strdup_printf("Warnings: %u (%u)", ss->warn_table.num_procs, ss->warn_events);
+    gtk_label_set_text( GTK_LABEL(ss->warn_label), buf);
+    g_free(buf);
+
+    buf = g_strdup_printf("Notes: %u (%u)", ss->note_table.num_procs, ss->note_events);
+    gtk_label_set_text( GTK_LABEL(ss->note_label), buf);
+    g_free(buf);
+
+    buf = g_strdup_printf("Chats: %u (%u)", ss->chat_table.num_procs, ss->chat_events);
+    gtk_label_set_text( GTK_LABEL(ss->chat_label), buf);
     g_free(buf);
 
     buf = g_strdup_printf("Details: %u", ss->disp_events);
     gtk_label_set_text( GTK_LABEL(ss->all_label), buf);
     g_free(buf);
-
-    return 1; /* Draw */
+    
 }
 
-
 static void
 win_destroy_cb(GtkWindow *win _U_, gpointer data)
 {
     expert_comp_dlg_t *ss=(expert_comp_dlg_t *)data;
-       expert_tapdata_t * etd=(expert_tapdata_t *)data;
 
     protect_thread_critical_region();
     remove_tap_listener(ss);
-    remove_tap_listener(etd);
     unprotect_thread_critical_region();
 
     free_error_table_data(&ss->error_table);
@@ -195,19 +204,6 @@ win_destroy_cb(GtkWindow *win _U_, gpointer data)
 
 }
 
-
-static void
-expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
-{
-       expert_tapdata_t *etd=(expert_tapdata_t *)data;
-
-       protect_thread_critical_region();
-       remove_tap_listener(etd);
-       unprotect_thread_critical_region();
-
-       g_free(etd);
-}
-
 static void
 expert_comp_init(const char *optarg _U_, void* userdata _U_)
 {
@@ -226,24 +222,13 @@ expert_comp_init(const char *optarg _U_, void* userdata _U_)
 
     ss=g_malloc(sizeof(expert_comp_dlg_t));
 
-    etd=g_malloc(sizeof(expert_tapdata_t));
-    etd->table = NULL;
-    etd->all_events = NULL;
-    etd->new_events = NULL;
-    etd->disp_events = 0;
-    etd->chat_events = 0;
-    etd->note_events = 0;
-    etd->warn_events = 0;
-    etd->error_events = 0;
-    etd->severity_report_level = PI_CHAT;
-
     ss->disp_events = 0;
     ss->chat_events = 0;
     ss->note_events = 0;
     ss->warn_events = 0;
     ss->error_events = 0;
 
-       ss->win=dlg_window_new("err");  /* transient_for top_level */
+       expert_comp_dlg_w = ss->win=dlg_window_new("err");  /* transient_for top_level */
        gtk_window_set_destroy_with_parent (GTK_WINDOW(ss->win), TRUE);
     gtk_window_set_default_size(GTK_WINDOW(ss->win), 700, 300);
 
@@ -300,15 +285,14 @@ expert_comp_init(const char *optarg _U_, void* userdata _U_)
     ss->all_label = gtk_label_new("Details: 0");
     gtk_notebook_append_page(GTK_NOTEBOOK(main_nb), temp_page, ss->all_label);
 
+    etd = expert_dlg_new_table();
     etd->label=gtk_label_new("Please wait ...");
     gtk_misc_set_alignment(GTK_MISC(etd->label), 0.0f, 0.5f);
 
     etd->win=ss->win;
     expert_dlg_init_table(etd, temp_page);
 
-
     /* Add tap listener functions for expert details, From expert_dlg.c*/
-
     error_string=register_tap_listener("expert", etd, NULL /* fstring */,
                                        0,
                                        expert_dlg_reset,
@@ -326,7 +310,7 @@ expert_comp_init(const char *optarg _U_, void* userdata _U_)
 
     /* Register the tap listener */
 
-    error_string=register_tap_listener("expert", ss, filter, 0, error_reset, error_packet, NULL);
+    error_string=register_tap_listener("expert", ss, filter, 0, error_reset, error_packet, expert_comp_draw);
     if(error_string){
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "%s", error_string->str);
         g_string_free(error_string, TRUE);
@@ -369,12 +353,18 @@ expert_comp_init(const char *optarg _U_, void* userdata _U_)
      * Put our window back in front
      */
     gdk_window_raise(ss->win->window);
+       /* Set the lable text */
+       expert_comp_draw(ss);
 }
 
 void
 expert_comp_dlg_cb(GtkWidget *w _U_, gpointer d _U_)
 {
-    expert_comp_init("", NULL);
+    if (expert_comp_dlg_w) {
+          reactivate_window(expert_comp_dlg_w);
+    } else {
+          expert_comp_init("", NULL);
+    }
 }
 
 void
index 420490147d15d6e8b4a08d69efffa02fc9d9a01d..8e799b8cf73223356c253ca476e896b29fd9b368 100644 (file)
@@ -37,6 +37,8 @@
 #include <gtk/gtk.h>
 
 #include "epan/packet_info.h"
+#include "epan/strutil.h"
+
 #include <epan/expert.h>
 
 #include "../simple_dialog.h"
@@ -101,15 +103,17 @@ enum
 
 static gint find_summary_data(error_equiv_table *err, const expert_info_t *expert_data)
 {
-    gint i;
+    guint i;
+    error_procedure_t *procedure;
     
     /* First time thru values will be 0 */
     if (err->num_procs==0) {
         return -1;
     }
     for (i=0;i<err->num_procs;i++) {
-        if (strcmp(err->procedures[i].entries[1], expert_data->protocol) == 0 &&
-            strcmp(err->procedures[i].entries[2], expert_data->summary) == 0) {
+        procedure = &g_array_index(err->procs_array, error_procedure_t, i);
+        if (strcmp(procedure->entries[1], expert_data->protocol) == 0 &&
+            strcmp(procedure->entries[2], expert_data->summary) == 0) {
             return i;
         }
     }
@@ -121,8 +125,9 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
 {
     int action, type, selection;
     error_equiv_table *err = (error_equiv_table *)callback_data;
-    char str[256];
+    char str[512];
     const char *current_filter;
+    error_procedure_t *procedure;
 
     GtkTreeIter iter;
     GtkTreeModel *model;
@@ -144,7 +149,6 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
     if (strcmp(grp, "Packet:")==0) {
         simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "You cannot filter or search for packet number. Click on a valid item header.");
         g_free(grp);
-        g_free(expert_data.protocol);
         g_free(expert_data.summary);
         return;
     }
@@ -157,7 +161,6 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
     /*       will also need to be stored in the TreeModel).                      */
     selection = find_summary_data(err, &expert_data);
 
-    g_free(expert_data.protocol);
     g_free(expert_data.summary);
 
     if(selection>=(int)err->num_procs){
@@ -168,64 +171,72 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
 
     /* Some expert data doesn't pass an expert item. Without this we cannot create a filter */
     /* But allow for searching of internet for error string */
-    if (action != 6 && action != 7) {
-        if (err->procedures[selection].fvalue_value==NULL) {
-            if (action != 2 && action != 3 && action != 4) {
-                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Wireshark cannot create a filter on this item - %s, try using find instead.", err->procedures[selection].entries[2]);
+    procedure = &g_array_index(err->procs_array, error_procedure_t, selection);
+
+    /* FIXME what is 7 ?*/
+    if (action != ACTION_WEB_LOOKUP && action != 7) {
+        char *msg;
+        if (0 /*procedure->fvalue_value==NULL*/) {
+            if (action != ACTION_FIND_FRAME && action != ACTION_FIND_NEXT && action != ACTION_FIND_PREVIOUS) {
+                simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Wireshark cannot create a filter on this item - %s, try using find instead.", 
+                              procedure->entries[2]);
                 return;
             }
         }
+        msg = g_malloc(escape_string_len(procedure->entries[2]));
+        escape_string(msg, procedure->entries[2]);
         switch(type){
         case ACTYPE_SELECTED:
             /* if no expert item was passed */
-            if (err->procedures[selection].fvalue_value==NULL) {
-                g_strlcpy(str, err->procedures[selection].entries[2], sizeof(str));
+            if (procedure->fvalue_value==NULL) {
+                g_snprintf(str, sizeof(str), "expert.message==%s", msg);
             }
             else
             {
                 /* expert item exists. Use it. */
-                g_strlcpy(str, err->procedures[selection].fvalue_value, sizeof(str));
+                g_strlcpy(str, procedure->fvalue_value, sizeof(str));
             }
             break;
         case ACTYPE_NOT_SELECTED:
             /* if no expert item was passed */
-            if (err->procedures[selection].fvalue_value==NULL) {
-                g_snprintf(str, sizeof(str), "!%s", err->procedures[selection].entries[2]);
+            if (procedure->fvalue_value==NULL) {
+                g_snprintf(str, sizeof(str), "!(expert.message==%s)", msg);
             }
             else
             {
                 /* expert item exists. Use it. */
-                g_snprintf(str, sizeof(str), "!(%s)", err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "!(%s)", procedure->fvalue_value);
             }
             break;
             /* the remaining cases will only exist if the expert item exists so no need to check */
         case ACTYPE_AND_SELECTED:
             if ((!current_filter) || (0 == strlen(current_filter)))
-                g_strlcpy(str, err->procedures[selection].fvalue_value, sizeof(str));
+                g_snprintf(str, sizeof(str), "expert.message==%s", msg);
             else
-                g_snprintf(str, sizeof(str), "(%s) && (%s)", current_filter, err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "(%s) && (expert.message==%s)", current_filter, msg);
             break;
         case ACTYPE_OR_SELECTED:
             if ((!current_filter) || (0 == strlen(current_filter)))
-                g_strlcpy(str, err->procedures[selection].fvalue_value, sizeof(str));
+                g_snprintf(str, sizeof(str), "expert.message==%s", msg);
             else
-                g_snprintf(str, sizeof(str), "(%s) || (%s)", current_filter, err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "(%s) || (expert.message==%s)", current_filter, msg);
             break;
         case ACTYPE_AND_NOT_SELECTED:
             if ((!current_filter) || (0 == strlen(current_filter)))
-                g_snprintf(str, sizeof(str), "!(%s)", err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "!(expert.message==%s)", msg);
             else
-                g_snprintf(str, sizeof(str), "(%s) && !(%s)", current_filter, err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "(%s) && !(expert.message==%s)", current_filter, msg);
             break;
         case ACTYPE_OR_NOT_SELECTED:
             if ((!current_filter) || (0 == strlen(current_filter)))
-                g_snprintf(str, sizeof(str), "!(%s)", err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "!(expert.message==%s)", msg);
             else
-                g_snprintf(str, sizeof(str), "(%s) || !(%s)", current_filter, err->procedures[selection].fvalue_value);
+                g_snprintf(str, sizeof(str), "(%s) || !(expert.message==%s)", current_filter, msg);
             break;
         default:
             simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Can't find menu type - %u", type);
         }
+        g_free(msg);
     }
 
     switch(action){
@@ -253,7 +264,7 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
          * A better aproach would be to attempt in capturing the last find string and utilize this 
          * with a find next/previous. Also a better approach might be to just send a <Ctl-N> keystroke.
          */
-        if (err->procedures[selection].fvalue_value==NULL) {
+        if (procedure->fvalue_value==NULL) {
             find_frame_with_filter(str);
         }
         else
@@ -271,7 +282,7 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
          * A better aproach would be to attempt in capturing the last find string and utilize this 
          * with a find next/previous. Also a better approach might be to just send a <Ctl-B> keystroke.
          */
-        if (err->procedures[selection].fvalue_value==NULL) {
+        if (procedure->fvalue_value==NULL) {
             find_frame_with_filter(str);
         }
         else
@@ -285,7 +296,7 @@ error_select_filter_cb(GtkWidget *widget _U_, gpointer callback_data, guint call
         break;
     case ACTION_WEB_LOOKUP:
         /* Lookup expert string on internet. Default search via www.google.com */
-        g_snprintf(str, sizeof(str), "http://www.google.com/search?hl=en&q=%s+'%s'", err->procedures[selection].entries[1], err->procedures[selection].entries[2]);
+        g_snprintf(str, sizeof(str), "http://www.google.com/search?hl=en&q=%s+'%s'", procedure->entries[1], procedure->entries[2]);
         browser_open_url(str);
         break;
     default:
@@ -434,9 +445,8 @@ error_create_popup_menu(error_equiv_table *err)
 }
 
 void
-init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox)
+init_error_table(error_equiv_table *err, guint num_procs, GtkWidget *vbox)
 {
-    guint16 i, j;
     GtkTreeStore *store;
     GtkWidget *tree;
     GtkTreeViewColumn *column;
@@ -445,9 +455,15 @@ init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox)
 
     /* Create the store */
     store = gtk_tree_store_new (4,       /* Total number of columns */
+#if 0
+                               G_TYPE_POINTER,   /* Group              */
+                               G_TYPE_POINTER,   /* Protocol           */
+                               G_TYPE_POINTER,   /* Summary            */
+#else
                                G_TYPE_STRING,   /* Group              */
                                G_TYPE_STRING,   /* Protocol           */
                                G_TYPE_STRING,   /* Summary            */
+#endif
                                G_TYPE_INT);     /* Count              */
 
     /* Create a view */
@@ -510,12 +526,9 @@ init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox)
     gtk_widget_show(err->scrolled_window);
 
     err->num_procs=num_procs;
-    err->procedures=g_malloc(sizeof(error_procedure_t)*(num_procs+1));
-    for(i=0;i<num_procs;i++){
-        for(j=0;j<3;j++){
-            err->procedures[i].entries[j]=NULL; /* reset all values */
-        }
-    }
+
+    err->text = g_string_chunk_new(100);
+    err->procs_array = g_array_sized_new(FALSE, FALSE, sizeof(error_procedure_t), num_procs);
 
     /* create popup menu for this table */
     error_create_popup_menu(err);
@@ -524,90 +537,71 @@ init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox)
 void
 init_error_table_row(error_equiv_table *err, const expert_info_t *expert_data)
 {
-    guint16 old_num_procs=err->num_procs;
-    guint16 j;
+    guint old_num_procs=err->num_procs;
+    guint j;
     gint row=0;
-
+    error_procedure_t *procedure;
     GtkTreeStore *store;
+    GtkTreeIter   new_iter;
 
     /* we have discovered a new procedure. Extend the table accordingly */
     row = find_summary_data(err, expert_data);
     if(row==-1){
+        error_procedure_t new_procedure;
         /* First time we have seen this event so initialize memory table */
         row = old_num_procs; /* Number of expert events since this is a new event */
-        err->procedures=g_realloc(err->procedures, (sizeof(error_procedure_t)*(old_num_procs+1)));
-        err->procedures[row].count=0; /* count of events for this item */
-        err->procedures[row].fvalue_value = NULL; /* Filter string value */
+
+        new_procedure.count=0; /* count of events for this item */
+        new_procedure.fvalue_value = NULL; /* Filter string value */
         for(j=0;j<4;j++){
-            err->procedures[row].entries[j]=NULL;
+            new_procedure.entries[j]=NULL;
         }
+        g_array_append_val(err->procs_array, new_procedure);
+        procedure = &g_array_index(err->procs_array, error_procedure_t, row);
         
         /* Create the item in our memory table */
-        err->procedures[row].entries[0]=(char *)g_strdup(val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"));  /* Group */
-        err->procedures[row].entries[1]=(char *)g_strdup(expert_data->protocol);    /* Protocol */
-        err->procedures[row].entries[2]=(char *)g_strdup(expert_data->summary);     /* Summary */
+        procedure->entries[0]=(char *)g_string_chunk_insert(err->text, 
+                val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"));  /* Group */
+        procedure->entries[1]=(char *)g_string_chunk_insert(err->text, expert_data->protocol);    /* Protocol */
+        procedure->entries[2]=(char *)g_string_chunk_insert(err->text, expert_data->summary);     /* Summary */
 
         /* Create a new item in our tree view */
         store = GTK_TREE_STORE(gtk_tree_view_get_model(err->tree_view)); /* Get store */
-        gtk_tree_store_append (store, &err->procedures[row].iter, NULL);  /* Acquire an iterator */
+        gtk_tree_store_append (store, &procedure->iter, NULL);  /* Acquire an iterator */
+        
+        gtk_tree_store_set (store, &procedure->iter,
+                    GROUP_COLUMN, procedure->entries[0],
+                    PROTOCOL_COLUMN, procedure->entries[1],
+                    SUMMARY_COLUMN,  procedure->entries[2], -1);
         
-        /* (Note: gtk_tree_store_set *copies* the input strings) */
-        gtk_tree_store_set (store, &err->procedures[row].iter,
-                            GROUP_COLUMN,    val_to_str(expert_data->group, expert_group_vals,"Unknown group (%u)"),
-                            PROTOCOL_COLUMN, expert_data->protocol,
-                            SUMMARY_COLUMN,  expert_data->summary,
-                            -1);
-
         /* If an expert item was passed then build the filter string */
         if (expert_data->pitem) {
             char *filter;
 
             filter = proto_construct_match_selected_string(PITEM_FINFO(expert_data->pitem), NULL);
             if (filter != NULL)
-                err->procedures[row].fvalue_value = g_strdup(filter);
+                procedure->fvalue_value = g_string_chunk_insert(err->text, filter);
         }
         /* Store the updated count of events */
         err->num_procs = ++old_num_procs;
     }
 
     /* Update our memory table with event data */
-    err->procedures[row].count++; /* increment the count of events for this item */
+    procedure = &g_array_index(err->procs_array, error_procedure_t, row);
+    procedure->count++; /* increment the count of events for this item */
 
+#if 0
     /* Store the updated count for this event item */
     err->procedures[row].entries[3]=(char *)g_strdup_printf("%d", err->procedures[row].count);     /* Count */
+#endif
 
     /* Update the tree with new count for this event */
     store = GTK_TREE_STORE(gtk_tree_view_get_model(err->tree_view));
-    gtk_tree_store_set(store, &err->procedures[row].iter, COUNT_COLUMN, err->procedures[row].count, -1);
-}
-
-void
-add_error_table_data(error_equiv_table *err, const expert_info_t *expert_data)
-{
-    error_procedure_t *errp;
-    gint index;
-    GtkTreeStore    *store;
-    GtkTreeIter      new_iter;
-    gchar            str[16];
-
-    index = find_summary_data(err, expert_data);
-
-    /* We should never encounter a condition where we cannot find the expert data. If
-     * we do then we will just abort.
-     */
-    if (index == -1) {
-        simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK, "Could not find expert data. Aborting");
-        return;
-    }
-    errp=&err->procedures[index];
-
-    store = GTK_TREE_STORE(gtk_tree_view_get_model(err->tree_view));
-
-    g_snprintf(str, sizeof(str), "%d", expert_data->packet_num);
-    gtk_tree_store_append(store, &new_iter, &errp->iter);
+    gtk_tree_store_set(store, &procedure->iter, COUNT_COLUMN, procedure->count, -1);
+    gtk_tree_store_append(store, &new_iter, &procedure->iter);
     gtk_tree_store_set(store, &new_iter,
                        GROUP_COLUMN,    "Packet:",
-                       PROTOCOL_COLUMN, str,
+                       PROTOCOL_COLUMN, (char *)g_strdup_printf("%d", expert_data->packet_num),
                        COUNT_COLUMN,    1,
                        -1);
 }
@@ -615,36 +609,20 @@ add_error_table_data(error_equiv_table *err, const expert_info_t *expert_data)
 void
 reset_error_table_data(error_equiv_table *err)
 {
-    guint16 i;
     GtkTreeStore    *store;
 
-    for(i=0;i<err->num_procs;i++){
-        err->procedures[i].entries[0] = NULL;
-        err->procedures[i].entries[1] = NULL;
-        err->procedures[i].entries[2] = NULL;
-        err->procedures[i].entries[3] = NULL;
-        err->procedures[i].count=0;
-    }
-
     store = GTK_TREE_STORE(gtk_tree_view_get_model(err->tree_view));
     gtk_tree_store_clear(store);
     err->num_procs = 0;
+    g_string_chunk_clear(err->text);
+    g_array_set_size(err->procs_array, 0);
 }
 
 void
 free_error_table_data(error_equiv_table *err)
 {
-    guint16 i,j;
 
-    for(i=0;i<err->num_procs;i++){
-        for(j=0;j<4;j++){
-            if(err->procedures[i].entries[j]){
-                err->procedures[i].entries[j]=NULL;
-            }
-            err->procedures[i].fvalue_value=NULL;
-            err->procedures[i].count=0;
-        }
-    }
-    err->procedures=NULL;
     err->num_procs=0;
+    g_string_chunk_free(err->text);
+    g_array_free(err->procs_array, TRUE);
 }
index 63335980f1b7f0c41876473b103ab20296733a9a..0645266de5851f86f1edb7b4bbcf01ab05835d5e 100644 (file)
@@ -27,6 +27,7 @@
 
 #include <gtk/gtk.h>
 #include <epan/expert.h>
+#include <gtk/expert_dlg.h>
 
 /** @file
  *  Helper routines common to all error statistics tap.
@@ -37,7 +38,7 @@ typedef struct _error_procedure_t {
        char    *entries[4];       /**< column entries */
     char    *fvalue_value;     /**< filter value */
     GtkTreeIter      iter;
-    guint16 count;             /**< number of expert items encountered
+    guint count;             /**< number of expert items encountered
                                     for this entry */
 } error_procedure_t;
 
@@ -47,32 +48,18 @@ typedef struct _error_equiv_table {
     GtkTreeSelection *select;           /**< item selected */
     GtkTreeView      *tree_view;        /**< Tree view */
        GtkWidget *menu;                    /**< context menu */
-       guint16 num_procs;                  /**< number of elements on procedures array */
-       error_procedure_t *procedures;      /**< the procedures array */
+       guint      num_procs;               /**< number of elements on procedures array */
+       GArray                    *procs_array;         /**< the procedures array error_procedure_t *procedures */
+       GStringChunk*     text;
 }error_equiv_table;
 
-typedef struct _expert_tapdata_s {
-       GtkWidget       *win;
-       GtkWidget       *scrolled_window;
-       GtkCList        *table;
-       GtkWidget       *label;
-       GList           *all_events;
-       GList           *new_events;
-       guint32         disp_events;
-       guint32         chat_events;
-       guint32         note_events;
-       guint32         warn_events;
-       guint32         error_events;
-       int                     severity_report_level;
-} expert_tapdata_t;
-
 /** Init an err table data structure.
  *
  * @param err the err table to init
  * @param num_procs number of procedures
  * @param vbox the corresponding GtkVBox to fill in
  */
-void init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox);
+void init_error_table(error_equiv_table *err, guint num_procs, GtkWidget *vbox);
 
 /** Init an err table row data structure.
  *
@@ -81,13 +68,6 @@ void init_error_table(error_equiv_table *err, guint16 num_procs, GtkWidget *vbox
  */
 void init_error_table_row(error_equiv_table *err, const expert_info_t *expert_data);
 
-/** Add err response to table row data. This will not draw the data!
- *
- * @param err the err table
- * @param expert data
- */
-void add_error_table_data(error_equiv_table *err, const expert_info_t *expert_data);
-
 /** Draw the err table data.
  *
  * @param err the err table
@@ -106,8 +86,3 @@ void reset_error_table_data(error_equiv_table *err);
  */
 void free_error_table_data(error_equiv_table *err);
 
-/* Function is located in expert_dlg.c */
-extern void expert_dlg_init_table(expert_tapdata_t * etd, GtkWidget *vbox);
-extern void expert_dlg_reset(void *tapdata);
-extern int expert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer);
-extern void expert_dlg_draw(void *data);
index bb434e155dc991c9c43facb13c6faf74752f7b93..98804d746426129183ac3c50586c815b34cbc762 100644 (file)
@@ -60,7 +60,7 @@
 #include "gtk/color_utils.h"
 #include "gtk/main_proto_draw.h"
 #include "gtk/help_dlg.h"
-
+#include "gtk/expert_dlg.h"
 
 static const value_string expert_severity_om_vals[] = {
        { PI_ERROR,             "Errors only" },
@@ -70,21 +70,6 @@ static const value_string expert_severity_om_vals[] = {
        { 0, NULL }
 };
 
-typedef struct expert_tapdata_s {
-       GtkWidget       *win;
-       GtkWidget       *scrolled_window;
-       GtkCList        *table;
-       GtkWidget       *label;
-       GList           *all_events;
-       GList           *new_events;
-       guint32         disp_events;
-       guint32         chat_events;
-       guint32         note_events;
-       guint32         warn_events;
-       guint32         error_events;
-       int                     severity_report_level;
-} expert_tapdata_t;
-
 
 /* reset of display only, e.g. for filtering */
 static void expert_dlg_display_reset(expert_tapdata_t * etd)
@@ -105,25 +90,28 @@ void expert_dlg_reset(void *tapdata)
 {
        expert_tapdata_t * etd = tapdata;
 
-       g_list_free(etd->all_events);
-       etd->all_events = NULL;
-       g_list_free(etd->new_events);
-       etd->new_events = NULL;
        etd->chat_events = 0;
        etd->note_events = 0;
        etd->warn_events = 0;
        etd->error_events = 0;
+       etd->last = 0;
+       etd->first = 0;
+       g_string_chunk_clear(etd->text);
+       g_array_set_size(etd->ei_array, 0);
 
        expert_dlg_display_reset(etd);
 }
 
 int expert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt _U_, const void *pointer)
 {
-    expert_info_t      *ei = se_memdup(pointer,sizeof(expert_info_t));
-       expert_tapdata_t * etd = tapdata;
+    expert_info_t      *ei;
+    expert_tapdata_t * etd = tapdata;
 
-    ei->protocol = se_strdup(ei->protocol);
-    ei->summary = se_strdup(ei->summary);
+    g_array_append_val(etd->ei_array, *(expert_info_t *)pointer);
+    etd->last = etd->ei_array->len;
+    ei = &g_array_index(etd->ei_array, expert_info_t, etd->last -1); /* ugly */
+    ei->protocol = ei->protocol;
+    ei->summary = g_string_chunk_insert_const(etd->text, ei->summary);
 
        switch(ei->severity) {
        case(PI_CHAT):
@@ -141,10 +129,6 @@ int expert_dlg_packet(void *tapdata, packet_info *pinfo _U_, epan_dissect_t *edt
        default:
                g_assert_not_reached();
        }
-
-       /* insert(0) is a *lot* faster than append! */
-       etd->new_events = g_list_insert(etd->new_events, ei, 0);
-
        if(ei->severity < etd->severity_report_level) {
                return 0; /* draw not required */
        } else {
@@ -158,7 +142,6 @@ expert_dlg_draw(void *data)
        expert_tapdata_t *etd = data;
        int row;
        int displayed;
-       char *strp;
        expert_info_t *ei;
        gchar *title;
        const char *entries[5];   /**< column entries */
@@ -167,9 +150,8 @@ expert_dlg_draw(void *data)
        displayed = etd->disp_events;
 
        if(etd->label) {
-               if(etd->new_events != NULL) {
-                       title = g_strdup_printf("Adding: %u new messages",
-                               g_list_length(etd->new_events));
+               if(etd->last - etd->first) {
+                       title = g_strdup_printf("Adding: %u new messages",etd->last - etd->first);
                        gtk_label_set_text(GTK_LABEL(etd->label), title);
                        g_free(title);
                }
@@ -178,12 +160,9 @@ expert_dlg_draw(void *data)
        gtk_clist_freeze(etd->table);
 
        /* append new events (remove from new list, append to displayed list and clist) */
-       while(etd->new_events != NULL){
-               ei = etd->new_events->data;
-
-               etd->new_events = g_list_remove(etd->new_events, ei);
-               /* insert(0) is a *lot* faster than append! */
-               etd->all_events = g_list_insert(etd->all_events, ei, 0);
+       while(etd->first < etd->last){
+               ei = &g_array_index(etd->ei_array, expert_info_t, etd->first);
+               etd->first++;
 
                if(ei->severity < etd->severity_report_level) {
                        continue;
@@ -195,10 +174,10 @@ expert_dlg_draw(void *data)
 
                /* packet number */
                if(ei->packet_num) {
-                       /* XXX */
-                       strp= se_strdup_printf("%u", ei->packet_num);
-                       entries[0] = strp;
-                       /*entries[0] = itoa(ei->packet_num, str, 10);*/
+            char str_buf[10];
+
+                       g_snprintf(str_buf, sizeof(str_buf), "%u", ei->packet_num);
+                       entries[0] = str_buf;
                } else {
                        entries[0] = "-";
                }
@@ -222,7 +201,7 @@ expert_dlg_draw(void *data)
                /*gtk_clist_set_pixmap(etd->table, row, 5, ascend_pm, ascend_bm);*/
 
                row=gtk_clist_append(etd->table, (gchar **) entries);
-               gtk_clist_set_row_data(etd->table, row, ei);
+               gtk_clist_set_row_data(etd->table, row, GUINT_TO_POINTER(ei->packet_num));
 
                /* set rows background color depending on severity */
                switch(ei->severity) {
@@ -243,8 +222,10 @@ expert_dlg_draw(void *data)
                }
                gtk_clist_set_foreground(etd->table, row, &expert_color_foreground);
        }
+       
+       if (etd->table->sort_column || etd->table->sort_type != GTK_SORT_ASCENDING)
+        gtk_clist_sort(etd->table);
 
-       gtk_clist_sort(etd->table);
        /* column autosizing is very slow for large number of entries,
         * so do it only for the first 1000 of it
         * (there might be no large changes behind this amount) */
@@ -340,12 +321,9 @@ srt_click_column_cb(GtkCList *clist, gint column, gpointer data)
 static void
 select_row_cb(GtkCList *clist, gint row, gint column _U_, GdkEventButton *event _U_, gpointer user_data _U_)
 {
-       expert_info_t   *ei;
-
-
-       ei = (expert_info_t *) gtk_clist_get_row_data(clist, row);
+       guint num = GPOINTER_TO_UINT(gtk_clist_get_row_data(clist, row));
 
-       cf_goto_frame(&cfile, ei->packet_num);
+       cf_goto_frame(&cfile, num);
 }
 
 
@@ -424,7 +402,7 @@ expert_dlg_init_table(expert_tapdata_t * etd, GtkWidget *vbox)
        }*/
 }
 
-static void
+void
 expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
 {
        expert_tapdata_t *etd=(expert_tapdata_t *)data;
@@ -434,6 +412,8 @@ expert_dlg_destroy_cb(GtkWindow *win _U_, gpointer data)
        unprotect_thread_critical_region();
 
        /*free_srt_table_data(&etd->afp_srt_table);*/
+       g_array_free(etd->ei_array, TRUE);
+       g_string_chunk_free(etd->text);
        g_free(etd);
 }
 
@@ -451,8 +431,7 @@ expert_dlg_severity_cb(GtkWidget *w, gpointer data)
 
        /* "move" all events from "all" back to "new" lists */
        protect_thread_critical_region();
-       etd->new_events = g_list_concat(etd->new_events, etd->all_events);
-       etd->all_events = NULL;
+       etd->first = 0;
        unprotect_thread_critical_region();
 
        /* redraw table */
@@ -460,6 +439,16 @@ expert_dlg_severity_cb(GtkWidget *w, gpointer data)
        expert_dlg_draw(etd);
 }
 
+expert_tapdata_t * expert_dlg_new_table(void)
+{
+       expert_tapdata_t * etd;
+       etd=g_malloc0(sizeof(expert_tapdata_t));
+       
+       etd->ei_array = g_array_sized_new(FALSE, FALSE, sizeof(expert_info_t), 1000);
+       etd->text = g_string_chunk_new(100);
+       etd->severity_report_level = PI_CHAT;
+       return etd;
+}
 
 static void
 expert_dlg_init(const char *optarg, void* userdata _U_)
@@ -489,18 +478,8 @@ expert_dlg_init(const char *optarg, void* userdata _U_)
 
        proto_draw_colors_init();
 
-       etd=g_malloc(sizeof(expert_tapdata_t));
-       etd->all_events = NULL;
-       etd->new_events = NULL;
-       etd->disp_events = 0;
-       etd->chat_events = 0;
-       etd->note_events = 0;
-       etd->warn_events = 0;
-       etd->error_events = 0;
-       etd->severity_report_level = PI_CHAT;
-
-       etd->win=dlg_window_new("Wireshark: Expert Info");  /* transient_for top_level */
-       gtk_window_set_destroy_with_parent (GTK_WINDOW(etd->win), TRUE);
+       etd = expert_dlg_new_table();
+       etd->win=window_new(GTK_WINDOW_TOPLEVEL, "Wireshark: Expert Info");
        gtk_window_set_default_size(GTK_WINDOW(etd->win), 650, 600);
 
        vbox=gtk_vbox_new(FALSE, 3);