diff options
author | Guy Harris <guy@alum.mit.edu> | 2001-03-24 02:07:22 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2001-03-24 02:07:22 +0000 |
commit | 58369df4ef1f56a235db207e4015db50a820341f (patch) | |
tree | 795482bf6ee9ef567486025ec8f27f6048aa46be /proto_hier_stats.c | |
parent | 8f43649bcbe72141d66fc69460b89fafb5627878 (diff) |
Give the code that computes protocol statistics a progress dialog box,
as, on a large capture, it could take a significant amount of time.
Let the user stop the computation and, if they do, don't pop up the
statistics dialog box.
Create a new header file declaring the routines to create, update, and
destroy progress dialog boxes; those routines' APIs don't depend on
GTK+, but others declared in "ui_util.h" do, and we don't want to oblige
a source file to depend on GTK+ headers unless it uses a GTK+ API or an
API that depends on GTK+.
svn path=/trunk/; revision=3179
Diffstat (limited to 'proto_hier_stats.c')
-rw-r--r-- | proto_hier_stats.c | 79 |
1 files changed, 69 insertions, 10 deletions
diff --git a/proto_hier_stats.c b/proto_hier_stats.c index 4247d49c5e..bb28b7269e 100644 --- a/proto_hier_stats.c +++ b/proto_hier_stats.c @@ -1,7 +1,7 @@ /* proto_hier_stats.c * Routines for calculating statistics based on protocol. * - * $Id: proto_hier_stats.c,v 1.2 2001/03/23 21:55:36 guy Exp $ + * $Id: proto_hier_stats.c,v 1.3 2001/03/24 02:07:20 guy Exp $ * * Ethereal - Network traffic analyzer * By Gerald Combs <gerald@zing.org> @@ -30,11 +30,15 @@ #include "globals.h" #include "proto_hier_stats.h" +#include "progress_dlg.h" #include <wtap.h> #include <stdio.h> #include <glib.h> +/* Update the progress bar this many times when scanning the packet list. */ +#define N_PROGBAR_UPDATES 100 + static GNode* find_stat_node(GNode *parent_node, header_field_info *needle_hfinfo) { @@ -147,6 +151,11 @@ ph_stats_new(void) ph_stats_t *ps; frame_data *frame; guint tot_packets, tot_bytes; + progdlg_t *progbar; + gboolean stop_flag; + guint32 progbar_quantum; + guint32 progbar_nextstep; + int count; /* Initialize the data */ ps = g_new(ph_stats_t, 1); @@ -154,22 +163,72 @@ ph_stats_new(void) ps->tot_bytes = 0; ps->stats_tree = g_node_new(NULL); - frame = cfile.plist; + /* Update the progress bar when it gets to this value. */ + progbar_nextstep = 0; + /* When we reach the value that triggers a progress bar update, + bump that value by this amount. */ + progbar_quantum = cfile.count/N_PROGBAR_UPDATES; + /* Count of packets at which we've looked. */ + count = 0; + + stop_flag = FALSE; + progbar = create_progress_dlg("Computing protocol statistics", "Stop", + &stop_flag); + tot_packets = 0; tot_bytes = 0; - while (frame) { - /* Skip frames that are hidden due to the display filter */ - if (!frame->flags.passed_dfilter) { - continue; + for (frame = cfile.plist; frame != NULL; frame = frame->next) { + /* Update the progress bar, but do it only N_PROGBAR_UPDATES + times; when we update it, we have to run the GTK+ main + loop to get it to repaint what's pending, and doing so + may involve an "ioctl()" to see if there's any pending + input from an X server, and doing that for every packet + can be costly, especially on a big file. */ + if (count >= progbar_nextstep) { + /* let's not divide by zero. I should never be started + * with count == 0, so let's assert that + */ + g_assert(cfile.count > 0); + + update_progress_dlg(progbar, + (gfloat) count / cfile.count); + + progbar_nextstep += progbar_quantum; + } + + if (stop_flag) { + /* Well, the user decided to abort the statistics. + computation process Just stop. */ + break; } - process_frame(frame, ps); + /* Skip frames that are hidden due to the display filter. + XXX - should the progress bar count only packets that + passed the display filter? If so, it should + probably do so for other loops (see "file.c") that + look only at those packets. */ + if (frame->flags.passed_dfilter) { + process_frame(frame, ps); + + tot_packets++; + tot_bytes += frame->pkt_len; + } - tot_packets++; - tot_bytes += frame->pkt_len; + count++; + } - frame = frame->next; + /* We're done calculating the statistics; destroy the progress bar. */ + destroy_progress_dlg(progbar); + + if (stop_flag) { + /* + * We quit in the middle; throw away the statistics + * and return NULL, so our caller doesn't pop up a + * window with the incomplete statistics. + */ + ph_stats_free(ps); + return NULL; } ps->tot_packets = tot_packets; |