From Kovarththanan Rajaratnam:
- Compute and cache color/custom filters dynamically. - Delay column construction. svn path=/trunk/; revision=29370
This commit is contained in:
parent
72d8e6ad54
commit
ca335d25cb
|
@ -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)
|
||||
|
|
|
@ -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
37
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
|
||||
|
|
|
@ -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]);
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
Loading…
Reference in New Issue