aboutsummaryrefslogtreecommitdiffstats
path: root/cfile.c
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2011-04-25 05:33:07 +0000
committerGuy Harris <guy@alum.mit.edu>2011-04-25 05:33:07 +0000
commit678be392f16cda70c04059717022d9b2d100825a (patch)
tree7de19db35225461d7a3d9418e48e78bb803382fc /cfile.c
parentd687ba04fdac0a694ecc87c440a77537888598f6 (diff)
Make the packet count an unsigned value, as frame numbers are unsigned.
Make the loops that scan through all the packets do so by frame number, to abstract away the "next" and "previous" pointers in the frame_data structure. Add a routine to cfile.c to map frame numbers to frame_data structures, and put in some special case handling so scanning forward or backward through the packets is O(N) rather than O(N^2). svn path=/trunk/; revision=36846
Diffstat (limited to 'cfile.c')
-rw-r--r--cfile.c96
1 files changed, 83 insertions, 13 deletions
diff --git a/cfile.c b/cfile.c
index 89ab953d40..d993e7ab84 100644
--- a/cfile.c
+++ b/cfile.c
@@ -37,19 +37,21 @@ void
cap_file_init(capture_file *cf)
{
/* Initialize the capture file struct */
- cf->plist_start = NULL;
- cf->plist_end = NULL;
- cf->wth = NULL;
- cf->filename = NULL;
- cf->source = NULL;
- cf->user_saved = FALSE;
- cf->is_tempfile = FALSE;
- cf->rfcode = NULL;
- cf->dfilter = NULL;
- cf->has_snap = FALSE;
- cf->snap = WTAP_MAX_PACKET_SIZE;
- cf->count = 0;
- cf->redissecting = FALSE;
+ cf->plist_start = NULL;
+ cf->plist_end = NULL;
+ cf->wth = NULL;
+ cf->filename = NULL;
+ cf->source = NULL;
+ cf->user_saved = FALSE;
+ cf->is_tempfile = FALSE;
+ cf->rfcode = NULL;
+ cf->dfilter = NULL;
+ cf->has_snap = FALSE;
+ cf->snap = WTAP_MAX_PACKET_SIZE;
+ cf->count = 0;
+ cf->last_found_num = 0;
+ cf->last_found_fd = NULL;
+ cf->redissecting = FALSE;
}
void
@@ -64,3 +66,71 @@ cap_file_add_fdata(capture_file *cf, frame_data *fdata)
cf->plist_end = fdata;
}
+/*
+ * Find the frame_data for the specified frame number.
+ * Do some caching to make this work reasonably fast for
+ * forward and backward sequential passes through the packets.
+ */
+frame_data *
+cap_file_find_fdata(capture_file *cf, guint32 num)
+{
+ frame_data *fdata;
+
+ if (num == 0) {
+ /* There is no frame number 0 */
+ return NULL;
+ }
+
+ /*
+ * Did we remember a frame number from a sequential pass through
+ * the frames?
+ */
+ if (cf->last_found_num != 0) {
+ /*
+ * Yes. Is this that frame?
+ */
+ if (num == cf->last_found_num) {
+ /* Yes - return it. */
+ return cf->last_found_fd;
+ }
+
+ /*
+ * No. Is it the frame just after that frame?
+ */
+ if (num == cf->last_found_num + 1) {
+ /*
+ * Yes - if there is such a frame, remember it and return it.
+ */
+ fdata = cf->last_found_fd->next;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata; /* could be null, if there is no such frame */
+ }
+
+ /*
+ * No. Is it the frame just before that frame?
+ */
+ if (num == cf->last_found_num - 1) {
+ /*
+ * Yes - if there is such a frame, remember it and return it.
+ */
+ fdata = cf->last_found_fd->prev;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata; /* could be null, if there is no such frame */
+ }
+ }
+
+ for (fdata = cf->plist_start; fdata != NULL && fdata->num < num;
+ fdata = fdata->next)
+ ;
+ if (fdata != NULL) {
+ cf->last_found_num = num;
+ cf->last_found_fd = fdata;
+ }
+ return fdata;
+}