aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2001-03-24 02:07:22 +0000
committerGuy Harris <guy@alum.mit.edu>2001-03-24 02:07:22 +0000
commit58369df4ef1f56a235db207e4015db50a820341f (patch)
tree795482bf6ee9ef567486025ec8f27f6048aa46be
parent8f43649bcbe72141d66fc69460b89fafb5627878 (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
-rw-r--r--Makefile.am3
-rw-r--r--file.c3
-rw-r--r--gtk/progress_dlg.c4
-rw-r--r--gtk/proto_hier_stats_dlg.c20
-rw-r--r--progress_dlg.h61
-rw-r--r--proto_hier_stats.c79
-rw-r--r--ui_util.h34
7 files changed, 150 insertions, 54 deletions
diff --git a/Makefile.am b/Makefile.am
index 18e2c060a6..ae71558054 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1,7 +1,7 @@
# Makefile.am
# Automake file for Ethereal
#
-# $Id: Makefile.am,v 1.295 2001/03/23 19:22:02 jfoster Exp $
+# $Id: Makefile.am,v 1.296 2001/03/24 02:07:20 guy Exp $
#
# Ethereal - Network traffic analyzer
# By Gerald Combs <gerald@zing.org>
@@ -373,6 +373,7 @@ ethereal_SOURCES = \
filters.h \
globals.h \
menu.h \
+ progress_dlg.h \
proto_hier_stats.h \
proto_hier_stats.c \
simple_dialog.h \
diff --git a/file.c b/file.c
index 2d9406f3e3..d5dc0c766b 100644
--- a/file.c
+++ b/file.c
@@ -1,7 +1,7 @@
/* file.c
* File I/O routines
*
- * $Id: file.c,v 1.233 2001/03/23 14:43:59 jfoster Exp $
+ * $Id: file.c,v 1.234 2001/03/24 02:07:20 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -81,6 +81,7 @@
#include "menu.h"
#include "util.h"
#include "simple_dialog.h"
+#include "progress_dlg.h"
#include "ui_util.h"
#include "prefs.h"
#include "gtk/proto_draw.h"
diff --git a/gtk/progress_dlg.c b/gtk/progress_dlg.c
index a37ede57d1..6df6b72a46 100644
--- a/gtk/progress_dlg.c
+++ b/gtk/progress_dlg.c
@@ -1,7 +1,7 @@
/* progress_dlg.c
* Routines for progress-bar (modal) dialog
*
- * $Id: progress_dlg.c,v 1.8 2000/08/23 06:56:27 guy Exp $
+ * $Id: progress_dlg.c,v 1.9 2001/03/24 02:07:22 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -29,7 +29,7 @@
#include "gtkglobals.h"
#include "dlg_utils.h"
-#include "ui_util.h"
+#include "progress_dlg.h"
#define PROG_BAR_KEY "progress_bar"
diff --git a/gtk/proto_hier_stats_dlg.c b/gtk/proto_hier_stats_dlg.c
index aceec24b78..14a0dbdfe7 100644
--- a/gtk/proto_hier_stats_dlg.c
+++ b/gtk/proto_hier_stats_dlg.c
@@ -1,6 +1,6 @@
/* proto_hier_stats_dlg.c
*
- * $Id: proto_hier_stats_dlg.c,v 1.1 2001/03/22 23:54:47 gram Exp $
+ * $Id: proto_hier_stats_dlg.c,v 1.2 2001/03/24 02:07:22 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -113,10 +113,9 @@ fill_in_ctree(GtkWidget *tree, ph_stats_t *ps)
}
static void
-create_tree(GtkWidget *container)
+create_tree(GtkWidget *container, ph_stats_t *ps)
{
GtkWidget *sw, *tree;
- ph_stats_t *ps;
int i, height;
gchar *column_titles[NUM_STAT_COLUMNS] = {
"Protocol",
@@ -127,8 +126,6 @@ create_tree(GtkWidget *container)
"Last-Protocol Bytes",
};
- ps = ph_stats_new();
-
/* Scrolled Window */
sw = gtk_scrolled_window_new(NULL, NULL);
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
@@ -141,7 +138,7 @@ create_tree(GtkWidget *container)
/* XXX - get 'pos' to set vertical scroll-bar placement. */
/* XXX - set line style from preferences ???. */
- /* The titel bars do nothing. */
+ /* The title bars do nothing. */
gtk_clist_column_titles_passive(GTK_CLIST(tree));
/* Auto Resize all columns */
@@ -173,9 +170,18 @@ create_tree(GtkWidget *container)
void
proto_hier_stats_cb(GtkWidget *w, gpointer d)
{
+ ph_stats_t *ps;
GtkWidget *dlg, *bt, *vbox, *frame, *bbox;
const gchar *wname = "Protocol Hierarchy Statistics";
+ /* Get the statistics. */
+ ps = ph_stats_new();
+ if (ps == NULL) {
+ /* The user gave up before we finished; don't pop up
+ a statistics window. */
+ return;
+ }
+
dlg = dlg_window_new(wname);
vbox = gtk_vbox_new(FALSE, 5);
@@ -188,7 +194,7 @@ proto_hier_stats_cb(GtkWidget *w, gpointer d)
/* Data section */
- create_tree(frame);
+ create_tree(frame, ps);
/* Button row. We put it in an HButtonBox to
* keep it from expanding to the width of the window. */
diff --git a/progress_dlg.h b/progress_dlg.h
new file mode 100644
index 0000000000..b40a069c07
--- /dev/null
+++ b/progress_dlg.h
@@ -0,0 +1,61 @@
+/* progress_dlg.h
+ * Definitions for progress dialog box routines
+ *
+ * $Id: progress_dlg.h,v 1.1 2001/03/24 02:07:20 guy Exp $
+ *
+ * Ethereal - Network traffic analyzer
+ * By Gerald Combs <gerald@zing.org>
+ * Copyright 1998 Gerald Combs
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __PROGRESS_DLG_H__
+#define __PROGRESS_DLG_H__
+
+/*
+ * Progress (modal) dialog box routines.
+ */
+
+struct progdlg;
+
+typedef struct progdlg progdlg_t;
+
+/*
+ * Create and pop up the progress dialog; allocate a "progdlg_t"
+ * and initialize it to contain all information the implementation
+ * needs in order to manipulate the dialog, and return a pointer to
+ * it.
+ *
+ * The first argument is the title to give the dialog box; the second
+ * argument is the string to put in the "stop this operation" button;
+ * the third argument is a pointer to a Boolean variable that will be
+ * set to TRUE if the user hits that button.
+ */
+progdlg_t *create_progress_dlg(const gchar *title, const gchar *stop_title,
+ gboolean *stop_flag);
+
+/*
+ * Set the percentage value of the progress bar.
+ */
+void update_progress_dlg(progdlg_t *dlg, gfloat percentage);
+
+/*
+ * Destroy the progress bar.
+ */
+void destroy_progress_dlg(progdlg_t *dlg);
+
+#endif /* __PROGRESS_DLG_H__ */
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;
diff --git a/ui_util.h b/ui_util.h
index ebc66e3f11..97d828af3f 100644
--- a/ui_util.h
+++ b/ui_util.h
@@ -1,7 +1,7 @@
/* ui_util.h
* Definitions for UI utility routines
*
- * $Id: ui_util.h,v 1.6 2000/07/07 07:01:28 guy Exp $
+ * $Id: ui_util.h,v 1.7 2001/03/24 02:07:20 guy Exp $
*
* Ethereal - Network traffic analyzer
* By Gerald Combs <gerald@zing.org>
@@ -43,38 +43,6 @@ void reactivate_window(GtkWidget *);
/* Destroy all popup packet windows. */
void destroy_packet_wins(void);
-/*
- * Progress (modal) dialog box routines.
- */
-
-struct progdlg;
-
-typedef struct progdlg progdlg_t;
-
-/*
- * Create and pop up the progress dialog; allocate a "progdlg_t"
- * and initialize it to contain all information the implementation
- * needs in order to manipulate the dialog, and return a pointer to
- * it.
- *
- * The first argument is the title to give the dialog box; the second
- * argument is the string to put in the "stop this operation" button;
- * the third argument is a pointer to a Boolean variable that will be
- * set to TRUE if the user hits that button.
- */
-progdlg_t *create_progress_dlg(const gchar *title, const gchar *stop_title,
- gboolean *stop_flag);
-
-/*
- * Set the percentage value of the progress bar.
- */
-void update_progress_dlg(progdlg_t *dlg, gfloat percentage);
-
-/*
- * Destroy the progress bar.
- */
-void destroy_progress_dlg(progdlg_t *dlg);
-
#ifdef __cplusplus
}
#endif /* __cplusplus */