Make the packet count an unsigned value, as frame numbers are unsigned.
[obnox/wireshark/wip.git] / cfile.c
diff --git a/cfile.c b/cfile.c
index 89ab953d40bf1b5abff1926fc20184e5ff4b4e20..d993e7ab84b249ce313a99f444582392d1522024 100644 (file)
--- 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;
+}