diff options
author | Guy Harris <guy@alum.mit.edu> | 2011-04-25 05:33:07 +0000 |
---|---|---|
committer | Guy Harris <guy@alum.mit.edu> | 2011-04-25 05:33:07 +0000 |
commit | 678be392f16cda70c04059717022d9b2d100825a (patch) | |
tree | 7de19db35225461d7a3d9418e48e78bb803382fc /cfile.c | |
parent | d687ba04fdac0a694ecc87c440a77537888598f6 (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.c | 96 |
1 files changed, 83 insertions, 13 deletions
@@ -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; +} |