aboutsummaryrefslogtreecommitdiffstats
path: root/cfile.c
diff options
context:
space:
mode:
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;
+}