From Kovarththanan Rajaratnam:
authoretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 10 Aug 2009 20:52:56 +0000 (20:52 +0000)
committeretxrab <etxrab@f5534014-38df-0310-8fa8-9805f1628bb7>
Mon, 10 Aug 2009 20:52:56 +0000 (20:52 +0000)
- Compute and cache color/custom filters dynamically.
- Delay column construction.

git-svn-id: http://anonsvn.wireshark.org/wireshark/trunk@29370 f5534014-38df-0310-8fa8-9805f1628bb7

color_filters.c
epan/column-utils.c
file.c
gtk/new_packet_list.c
gtk/packet_list_store.c
gtk/packet_list_store.h
ui_util.h

index 25761a73886c009c4cf7ded927c3f52cb6f9ed9f..c30369121d079a72c3b7bfcd10584d2f83f718fd 100644 (file)
@@ -432,7 +432,8 @@ prime_edt(gpointer data, gpointer user_data)
 void
 color_filters_prime_edt(epan_dissect_t *edt)
 {
-       g_slist_foreach(color_filter_list, prime_edt, edt);
+       if (color_filters_used())
+               g_slist_foreach(color_filter_list, prime_edt, edt);
 }
 
 /* Colorize a single packet of the packet list (old packet list)
index 3fa2ac46281572876a5031d39cc4acae99b06ba8..e4dd9b15414c8fbfd6d5b71fed0f3f45fa0f5f10 100644 (file)
@@ -1409,6 +1409,9 @@ col_fill_in(packet_info *pinfo, gboolean fill_fd_colums)
 {
   int i;
 
+  if (!pinfo->cinfo)
+    return;
+
   for (i = 0; i < pinfo->cinfo->num_cols; i++) {
     switch (pinfo->cinfo->col_fmt[i]) {
 
diff --git a/file.c b/file.c
index 49e00156feed39412a41f2d25cdd467833372b79..620242d75c4f7b25057c77e4ca03fc5c296f906a 100644 (file)
--- a/file.c
+++ b/file.c
@@ -1003,6 +1003,13 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
   gint          row;
   gboolean     create_proto_tree = FALSE;
   epan_dissect_t *edt;
+  column_info *cinfo;
+
+#ifdef NEW_PACKET_LIST
+  cinfo = (tap_flags & TL_REQUIRES_COLUMNS) ? &cf->cinfo : NULL;
+#else
+  cinfo = &cf->cinfo;
+#endif
 
   /* just add some value here until we know if it is being displayed or not */
   fdata->cum_bytes  = cum_bytes + fdata->pkt_len;
@@ -1057,9 +1064,12 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
      allocate a protocol tree root node, so that we'll construct
      a protocol tree against which a filter expression can be
      evaluated. */
-  if ((dfcode != NULL && refilter) || color_filters_used() ||
-      filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE) ||
-      have_custom_cols(&cf->cinfo))
+  if ((dfcode != NULL && refilter) ||
+#ifndef NEW_PACKET_LIST
+      color_filters_used() ||
+      have_custom_cols(cinfo) ||
+#endif
+      filtering_tap_listeners || (tap_flags & TL_REQUIRES_PROTO_TREE))
          create_proto_tree = TRUE;
 
   /* Dissect the frame. */
@@ -1068,15 +1078,15 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
   if (dfcode != NULL && refilter) {
       epan_dissect_prime_dfilter(edt, dfcode);
   }
-  /* prepare color filters */
-  if (color_filters_used()) {
-      color_filters_prime_edt(edt);
-  }
 
-  col_custom_prime_edt(edt, &cf->cinfo);
+  /* prepare color filters */
+#ifndef NEW_PACKET_LIST
+  color_filters_prime_edt(edt);
+  col_custom_prime_edt(edt, cinfo);
+#endif
 
   tap_queue_init(edt);
-  epan_dissect_run(edt, pseudo_header, buf, fdata, &cf->cinfo);
+  epan_dissect_run(edt, pseudo_header, buf, fdata, cinfo);
   tap_push_tapped_queue(edt);
 
   /* If we have a display filter, apply it if we're refiltering, otherwise
@@ -1129,14 +1139,9 @@ add_packet_to_packet_list(frame_data *fdata, capture_file *cf,
     cf->last_displayed = fdata;
 
 #ifdef NEW_PACKET_LIST
-    /* This function returns the color_t that was applied to the packet (in
-     * the old packet list).  Applying the color to the packet is only done
-     * in the following function when not using the new packet list. */
-    fdata->color_filter = color_filters_colorize_packet(0, edt); 
-
-    row = new_packet_list_append(&cf->cinfo, fdata, &edt->pi);
+    row = new_packet_list_append(cinfo, fdata, &edt->pi);
 #else
-    row = packet_list_append(cf->cinfo.col_data, fdata);
+    row = packet_list_append(cinfo->col_data, fdata);
 
     /* colorize packet: first apply color filters
      * then if packet is marked, use preferences to overwrite color
index fa5252dc88a0b38cfc8c3b7615127e3b423df117..59039d3eb8d170d722dac0e85460629fc4b2c520 100644 (file)
@@ -43,6 +43,7 @@
 #include "epan/prefs.h"
 #include <epan/packet.h>
 #include "../ui_util.h"
+#include "../simple_dialog.h"
 #include "epan/emem.h"
 #include "globals.h"
 #include "gtk/gtkglobals.h"
@@ -104,18 +105,22 @@ new_packet_list_append(column_info *cinfo, frame_data *fdata, packet_info *pinfo
        gint i;
        row_data_t row_data;
 
-       /* Allocate the array holding column data, the size is the current number of columns
-
-        * XXX - only allocate storage for columns _not_ based on values from frame_data? */
-       row_data.col_text = se_alloc(sizeof(row_data.col_text)*cinfo->num_cols);
-
-       for(i = 0; i < cinfo->num_cols; i++) {
-               if (col_based_on_frame_data(cinfo, i))
-                       /* We already store the value in frame_data, so don't duplicate this. */
-                       row_data.col_text[i] = NULL;
-               else
-                       row_data.col_text[i] = se_strdup(cinfo->col_data[i]);
+       if (cinfo) {
+               /* Allocate the array holding column data, the size is the current number of columns */
+               row_data.col_text = se_alloc(sizeof(row_data.col_text)*packetlist->n_columns);
+               g_assert(packetlist->n_columns == cinfo->num_cols);
+               for(i = 0; i < cinfo->num_cols; i++) {
+                       if (col_based_on_frame_data(cinfo, i) ||
+                               /* We handle custom columns lazily */
+                               cinfo->col_fmt[i] == COL_CUSTOM)
+                               /* We already store the value in frame_data, so don't duplicate this. */
+                               row_data.col_text[i] = NULL;
+                       else
+                               row_data.col_text[i] = se_strdup(cinfo->col_data[i]);
+               }
        }
+       else
+               row_data.col_text = NULL;
 
        row_data.fdata = fdata;
 
@@ -435,6 +440,36 @@ row_from_iter(GtkTreeIter *iter)
        return record->pos;
 }
 
+static gboolean
+get_dissected_flag_from_iter(GtkTreeIter *iter)
+{
+       PacketListRecord *record;
+
+       record = iter->user_data;
+
+       return record->dissected;
+}
+
+static gboolean
+col_text_present_from_iter(GtkTreeIter *iter)
+{
+       PacketListRecord *record;
+
+       record = iter->user_data;
+
+       return record->col_text != NULL;
+}
+
+static void
+set_dissected_flag_from_iter(GtkTreeIter *iter, gboolean dissected)
+{
+       PacketListRecord *record;
+
+       record = iter->user_data;
+
+       record->dissected = dissected;
+}
+
 /* XXX: will this work with display filters? */
 static gboolean
 iter_from_row(GtkTreeIter *iter, guint row)
@@ -444,6 +479,65 @@ iter_from_row(GtkTreeIter *iter, guint row)
        return gtk_tree_model_iter_nth_child(model, iter, NULL, row);
 }
 
+static void
+new_packet_list_dissect(frame_data *fdata, gboolean col_text_present)
+{
+       epan_dissect_t *edt;
+       int err;
+       gchar *err_info;
+       column_info *cinfo;
+
+       /* We need to construct the columns if we skipped the columns entirely
+        * when reading the file or if we have custom columns enabled */
+       if (have_custom_cols(&cfile.cinfo) || !col_text_present)
+               cinfo = &cfile.cinfo;
+       else
+               cinfo = NULL;
+
+       if (!wtap_seek_read(cfile.wth, fdata->file_off, &cfile.pseudo_header,
+               cfile.pd, fdata->cap_len, &err, &err_info)) {
+                       simple_dialog(ESD_TYPE_ERROR, ESD_BTN_OK,
+                       cf_read_error_message(err, err_info), cfile.filename);
+                       return;
+       }
+
+       edt = epan_dissect_new(TRUE /* create_proto_tree */, FALSE /* proto_tree_visible */);
+       color_filters_prime_edt(edt);
+       col_custom_prime_edt(edt, &cfile.cinfo);
+       epan_dissect_run(edt, &cfile.pseudo_header, cfile.pd, fdata, cinfo);
+       fdata->color_filter = color_filters_colorize_packet(0 /* row - unused */, edt);
+
+       /* "Stringify" non frame_data vals */
+       if (!col_text_present)
+               epan_dissect_fill_in_columns(edt, FALSE /* fill_fd_colums */);
+
+       epan_dissect_free(edt);
+}
+
+static void
+cache_columns(frame_data *fdata, guint row, gboolean col_text_present)
+{
+       int col;
+
+       /* None of the columns are present. Fill them out in the record */
+       if (!col_text_present) {
+               for(col = 0; col < cfile.cinfo.num_cols; ++col) {
+                       /* Skip columns based om frame_data because we  already store those. */
+                       if (!col_based_on_frame_data(&cfile.cinfo, col))
+                               packet_list_change_record(packetlist, row, col, &cfile.cinfo);
+               }
+               return;
+       }
+
+       /* Custom columns are present. Fill them out in the record */
+       if (have_custom_cols(&cfile.cinfo))
+               for (col = cfile.cinfo.col_first[COL_CUSTOM];
+                        col <= cfile.cinfo.col_last[COL_CUSTOM];
+                        ++col)
+                       if (cfile.cinfo.col_fmt[col] == COL_CUSTOM)
+                               packet_list_change_record(packetlist, row, col, &cfile.cinfo);
+}
+
 static void
 show_cell_data_func(GtkTreeViewColumn *col _U_, GtkCellRenderer *renderer,
                    GtkTreeModel *model, GtkTreeIter *iter, gpointer data)
@@ -458,6 +552,16 @@ show_cell_data_func(GtkTreeViewColumn *col _U_, GtkCellRenderer *renderer,
        GdkColor bg_gdk;
        gchar *cell_text;
 
+       if (get_dissected_flag_from_iter(iter))
+               color_filter = fdata->color_filter;
+       else {
+               gboolean col_text_present = col_text_present_from_iter(iter);
+               new_packet_list_dissect(fdata, col_text_present);
+               set_dissected_flag_from_iter(iter, TRUE);
+               cache_columns(fdata, row, col_text_present);
+               color_filter = fdata->color_filter;
+       }
+
        if (col_based_on_frame_data(&cfile.cinfo, col_num)) {
                col_fill_in_frame_data(fdata, &cfile.cinfo, col_num);
                cell_text = g_strdup(cfile.cinfo.col_data[col_num]);
index e7c7eb163d69848683f4c4ec1544c9ec5c78d9c5..54c194f756ebe8818cc0de8c28213cae0718638c 100644 (file)
@@ -591,6 +591,7 @@ packet_list_append_record(PacketList *packet_list, row_data_t *row_data)
                                    packet_list->num_rows);
 
        newrecord = se_alloc(sizeof(PacketListRecord));
+       newrecord->dissected = FALSE;
        newrecord->col_text = row_data->col_text;
        newrecord->fdata = row_data->fdata;
        newrecord->pos = pos;
@@ -607,6 +608,23 @@ packet_list_append_record(PacketList *packet_list, row_data_t *row_data)
         */
 }
 
+void
+packet_list_change_record(PacketList *packet_list, guint row, gint col, column_info *cinfo)
+{
+       PacketListRecord *record;
+
+       g_return_if_fail(PACKETLIST_IS_LIST(packet_list));
+
+       g_assert(row < packet_list->num_rows);
+       record = packet_list->rows[row];
+       g_assert(record->pos == row);
+       g_assert(!record->col_text || (record->col_text[col] == NULL));
+       if (!record->col_text)
+               record->col_text = se_alloc0(sizeof(record->col_text)*packet_list->n_columns);
+
+       record->col_text[col] = se_strdup(cinfo->col_data[col]);
+}
+
 static gboolean
 packet_list_sortable_get_sort_column_id(GtkTreeSortable *sortable,
                                        gint *sort_col_id,
index c8ad14dfc0fdea6a1f2536f3494f6872fec72cc3..0e7d392b54dfa27e3e6cedf8dbda3a9f5b540472 100644 (file)
@@ -39,7 +39,6 @@
 
 typedef struct {
        gchar **col_text;
-       gchar **col_filter;
        frame_data *fdata;
 } row_data_t;
 
@@ -49,8 +48,8 @@ typedef struct _PacketListClass PacketListClass;
 
 /* PacketListRecord: represents a row */
 struct _PacketListRecord
-
 {
+       gboolean dissected;
        frame_data *fdata;
        gchar **col_text;
 
@@ -90,6 +89,7 @@ GType packet_list_list_get_type(void);
 PacketList *new_packet_list_new(void);
 void new_packet_list_store_clear(PacketList *packet_list);
 void packet_list_append_record(PacketList *packet_list, row_data_t *row_data);
+void packet_list_change_record(PacketList *packet_list, guint row, gint col, column_info *cinfo);
 
 #endif /* NEW_PACKET_LIST */
 
index 6816f1e8873d8db53d7fae90573cd22cb77e5b48..06cf29353acaf497401e14bdce0ae09923828b3f 100644 (file)
--- a/ui_util.h
+++ b/ui_util.h
@@ -27,7 +27,9 @@
 #ifndef __UI_UTIL_H__
 #define __UI_UTIL_H__
 
-#ifndef NEW_PACKET_LIST
+#ifdef NEW_PACKET_LIST
+#include "epan/packet_info.h"
+#else
 #include "color.h"
 #endif