a67e2c4b06d827520024f21bc5d80e1a271ea41a
[obnox/wireshark/wip.git] / epan / dfilter / drange.c
1 /* drange.c
2  * Routines for providing general range support to the dfilter library
3  *
4  * $Id: drange.c,v 1.3 2002/03/02 20:48:11 guy Exp $
5  * 
6  * Copyright (c) 2000 by Ed Warnicke <hagbard@physics.rutgers.edu>
7  *
8  * Ethereal - Network traffic analyzer
9  * By Gerald Combs
10  * Copyright 1999 Gerald Combs
11  * This program is free software; you can redistribute it and/or
12  * modify it under the terms of the GNU General Public License
13  * as published by the Free Software Foundation; either version 2
14  * of the License, or (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  */
25
26 #include "drange.h"
27
28 /* drange_node constructor */
29 drange_node*
30 drange_node_new(void)
31 {
32   drange_node* new_range_node;
33
34   new_range_node = g_malloc(sizeof(drange_node));
35   new_range_node->start_offset = 0;
36   new_range_node->length = 0;
37   new_range_node->end_offset = 0;
38   new_range_node->ending = UNINITIALIZED;
39   return new_range_node;
40 }
41
42 /* drange_node destructor */
43 void
44 drange_node_free(drange_node* drnode)
45 {
46   g_free(drnode);
47 }
48
49 /* drange_node accessors */  
50 gint
51 drange_node_get_start_offset(drange_node* drnode)
52 {
53   g_assert(drnode->ending != UNINITIALIZED);
54   return drnode->start_offset;
55 }
56
57 gint
58 drange_node_get_length(drange_node* drnode)
59 {
60   g_assert(drnode->ending == LENGTH);
61   return drnode->length;
62 }
63
64 gint
65 drange_node_get_end_offset(drange_node* drnode)
66 {
67   g_assert(drnode->ending == OFFSET);
68   return drnode->end_offset;
69 }
70
71 drange_node_end_t
72 drange_node_get_ending(drange_node* drnode)
73 {
74   g_assert(drnode->ending != UNINITIALIZED);
75   return drnode->ending;
76 }
77
78 /* drange_node mutators */
79 void
80 drange_node_set_start_offset(drange_node* drnode, gint offset)
81 {
82   drnode->start_offset = offset;
83 }
84
85 void
86 drange_node_set_length(drange_node* drnode, gint length)
87 {
88   drnode->length = length;
89   drnode->ending = LENGTH;
90 }
91
92 void
93 drange_node_set_end_offset(drange_node* drnode, gint offset)
94 {
95   drnode->end_offset = offset;
96   drnode->ending = OFFSET;
97 }
98
99
100 void
101 drange_node_set_to_the_end(drange_node* drnode)
102 {
103   drnode->ending = TO_THE_END;
104 }
105
106 /* drange constructor */
107 drange*
108 drange_new(void)
109 {
110   drange* new_drange;
111   new_drange = g_malloc(sizeof(drange));
112   new_drange->range_list = NULL;
113   new_drange->has_total_length = TRUE;
114   new_drange->total_length = 0;
115   new_drange->min_start_offset = G_MAXINT;
116   new_drange->max_start_offset = G_MININT;
117   return new_drange;
118 }
119
120 static void
121 drange_append_wrapper(gpointer data, gpointer user_data)
122 {
123         drange_node *drnode = data;
124         drange          *dr = user_data;
125
126         drange_append_drange_node(dr, drnode);
127 }
128
129 drange*
130 drange_new_from_list(GSList *list)
131 {
132         drange  *new_drange;
133
134         new_drange = drange_new();
135         g_slist_foreach(list, drange_append_wrapper, new_drange);
136         return new_drange;
137 }
138
139   
140 static void
141 drange_node_free_wrapper(gpointer data, gpointer userdata _U_)
142 {
143   g_free(data);
144 }
145
146 /* drange destructor */
147 void
148 drange_free(drange* dr)
149 {
150   drange_node_free_list(dr->range_list);
151   g_free(dr);
152 }
153
154 /* Call drange_node destructor on all list items */
155 void
156 drange_node_free_list(GSList* list)
157 {
158   g_slist_foreach(list, drange_node_free_wrapper, NULL);
159 }
160
161 /* drange accessors */
162 gboolean drange_has_total_length(drange* dr){ return dr->has_total_length; }
163 gint drange_get_total_length(drange* dr) { return dr->total_length; }
164 gint drange_get_min_start_offset(drange* dr) { return dr->min_start_offset; }
165 gint drange_get_max_start_offset(drange* dr) { return dr->max_start_offset; }
166     
167 static void
168 update_drange_with_node(drange *dr, drange_node *drnode)
169 {
170     if(drnode->ending == TO_THE_END){
171       dr->has_total_length = FALSE;
172     }
173     else if(dr->has_total_length){
174       dr->total_length += drnode->length;
175     }
176     if(drnode->start_offset < dr->min_start_offset){
177       dr->min_start_offset = drnode->start_offset;
178     }
179     if(drnode->start_offset > dr->max_start_offset){
180       dr->max_start_offset = drnode->start_offset;
181     }
182 }
183
184 /* drange mutators */
185 void
186 drange_prepend_drange_node(drange* dr, drange_node* drnode)
187 {
188   if(drnode != NULL){
189     dr->range_list = g_slist_prepend(dr->range_list,drnode);
190     update_drange_with_node(dr, drnode);
191   }  
192 }
193
194 void
195 drange_append_drange_node(drange* dr, drange_node* drnode)
196 {
197   if(drnode != NULL){
198     dr->range_list = g_slist_append(dr->range_list,drnode);
199     update_drange_with_node(dr, drnode);
200   }  
201 }
202
203 void
204 drange_foreach_drange_node(drange* dr, GFunc func, gpointer funcdata)
205 {
206   g_slist_foreach(dr->range_list,func,funcdata);
207 }