aboutsummaryrefslogtreecommitdiffstats
path: root/epan/range.c
diff options
context:
space:
mode:
authorMichael Mann <mmann78@netscape.net>2016-09-21 23:16:58 -0400
committerMichael Mann <mmann78@netscape.net>2016-09-22 13:49:42 +0000
commitd29b369bdcdf5bbc3f22b46e3ba0734c630dd3ad (patch)
tree3d4a5bec21a5b9ad23c5424b09a883a5bccdf6a7 /epan/range.c
parent69dfe97251cea64ba7a1506f5ca51bfed2bf24b3 (diff)
Add range_add_value and range_remove_value.
These APIs can insert or remove a single value into a range structure. Adding a value may extend an existing range or create a new one. Removing a value may remove a range item. Change-Id: Ia6995ecf7760aca1fb7fd9b4c53972298a57675f Reviewed-on: https://code.wireshark.org/review/17836 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
Diffstat (limited to 'epan/range.c')
-rw-r--r--epan/range.c93
1 files changed, 93 insertions, 0 deletions
diff --git a/epan/range.c b/epan/range.c
index b383e292cc..0bce5f9dea 100644
--- a/epan/range.c
+++ b/epan/range.c
@@ -280,6 +280,99 @@ value_is_in_range(range_t *range, guint32 val)
return(FALSE);
}
+/* This function returns TRUE if val has successfully been added to
+ * a range. This may extend an existing range or create a new one
+ */
+gboolean
+range_add_value(range_t **range, guint32 val)
+{
+ guint i;
+
+ if ((range) && (*range)) {
+ for (i=0; i < (*range)->nranges; i++) {
+ if (val >= (*range)->ranges[i].low && val <= (*range)->ranges[i].high)
+ return TRUE;
+
+ if (val == (*range)->ranges[i].low-1)
+ {
+ /* Sink to a new low */
+ (*range)->ranges[i].low = val;
+ return TRUE;
+ }
+
+ if (val == (*range)->ranges[i].high+1)
+ {
+ /* Reach a new high */
+ (*range)->ranges[i].high = val;
+ return TRUE;
+ }
+ }
+
+ (*range) = (range_t *)g_realloc((*range), RANGE_HDR_SIZE +
+ ((*range)->nranges+1)*sizeof (range_admin_t));
+ (*range)->nranges++;
+ (*range)->ranges[i].low = (*range)->ranges[i].high = val;
+ return TRUE;
+ }
+ return(FALSE);
+}
+
+/* This function returns TRUE if val has successfully been removed from
+ * a range. This may delete an existing range
+ */
+gboolean
+range_remove_value(range_t **range, guint32 val)
+{
+ guint i, j, new_j;
+ range_t *new_range;
+
+ if ((range) && (*range)) {
+ for (i=0; i < (*range)->nranges; i++) {
+
+ /* value is in the middle of the range, so it can't really be removed */
+ if (val > (*range)->ranges[i].low && val < (*range)->ranges[i].high)
+ return TRUE;
+
+ if ((val == (*range)->ranges[i].low) && (val == (*range)->ranges[i].high))
+ {
+ /* Remove the range item entirely */
+ new_range = (range_t*)g_malloc(RANGE_HDR_SIZE + ((*range)->nranges-1)*sizeof (range_admin_t));
+ new_range->nranges = (*range)->nranges-1;
+ for (j=0, new_j = 0; j < (*range)->nranges; j++) {
+
+ /* Skip the current range */
+ if (j == i)
+ continue;
+
+ new_range->ranges[new_j].low = (*range)->ranges[j].low;
+ new_range->ranges[new_j].high = (*range)->ranges[j].high;
+ new_j++;
+ }
+
+ g_free(*range);
+ *range = new_range;
+ return TRUE;
+ }
+
+ if (val == (*range)->ranges[i].low)
+ {
+ /* Raise low */
+ (*range)->ranges[i].low++;
+ return TRUE;
+ }
+
+ if (val == (*range)->ranges[i].high)
+ {
+ /* Reach a new high */
+ (*range)->ranges[i].high--;
+ return TRUE;
+ }
+ }
+ return TRUE;
+ }
+ return(FALSE);
+}
+
/* This function returns TRUE if the two given range_t's are equal.
*/
gboolean