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>
This commit is contained in:
Michael Mann 2016-09-21 23:16:58 -04:00
parent 69dfe97251
commit d29b369bdc
3 changed files with 111 additions and 0 deletions

View File

@ -1158,6 +1158,8 @@ libwireshark.so.0 libwireshark0 #MINVER#
range_copy@Base 1.9.1
range_empty@Base 1.9.1
range_foreach@Base 1.9.1
range_add_value@Base 2.3.0
range_remove_value@Base 2.3.0
ranges_are_equal@Base 1.9.1
read_disabled_heur_dissector_list@Base 1.99.8
read_disabled_protos_list@Base 1.12.0~rc1

View File

@ -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

View File

@ -103,6 +103,22 @@ convert_ret_t range_convert_str_work(range_t **range, const gchar *es,
*/
WS_DLL_PUBLIC gboolean value_is_in_range(range_t *range, guint32 val);
/** This function returns TRUE if val has successfully been added to
* a range. This may extend an existing range or create a new one
* @param range to add value
* @param val value to add to range
* @return TRUE if the value is successsfully added to range
*/
WS_DLL_PUBLIC gboolean range_add_value(range_t **range, guint32 val);
/** This function returns TRUE if val has successfully been removed from
* a range. This may remove an existing range.
* @param range to remove value
* @param val value to remove within range
* @return TRUE if the value is successsfully removed to range
*/
WS_DLL_PUBLIC gboolean range_remove_value(range_t **range, guint32 val);
/** This function returns TRUE if the two given range_t's are equal.
* @param a first range
* @param b second range