From Kovarththanan Rajaratnam:

- Compute and cache color/custom filters dynamically.
- Delay column construction.

svn path=/trunk/; revision=29370
This commit is contained in:
Anders Broman 2009-08-10 20:52:56 +00:00
parent 72d8e6ad54
commit ca335d25cb
7 changed files with 164 additions and 31 deletions

View 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)

View 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]) {

37
file.c
View File

@ -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

View 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]);

View 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,

View 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 */

View File

@ -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