Add APIs to remove option instances from blocks.

That will allow deletion of comments, stripping of options when
sanitizing captures, etc..

Change-Id: I9667ba2ccf4e548ff3b7d500796b260a437bcea0
Reviewed-on: https://code.wireshark.org/review/16485
Reviewed-by: Guy Harris <guy@alum.mit.edu>
This commit is contained in:
Guy Harris 2016-07-15 17:25:41 -07:00
parent 9dd2674fad
commit ae598d1737
2 changed files with 128 additions and 16 deletions

View File

@ -205,29 +205,35 @@ wtap_block_t wtap_block_create(wtap_block_type_t block_type)
return block;
}
static void wtap_block_free_option(wtap_block_t block, wtap_option_t *opt)
{
wtap_opttype_t *opttype;
opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
switch (opttype->data_type) {
case WTAP_OPTTYPE_STRING:
g_free(opt->value.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
opttype->free_func(opt->value.customval.data);
g_free(opt->value.customval.data);
break;
default:
break;
}
}
static void wtap_block_free_options(wtap_block_t block)
{
guint i;
wtap_option_t *opt;
wtap_opttype_t *opttype;
for (i = 0; i < block->options->len; i++) {
opt = &g_array_index(block->options, wtap_option_t, i);
opttype = &g_array_index(block->info->options, wtap_opttype_t, opt->option_id);
switch (opttype->data_type) {
case WTAP_OPTTYPE_STRING:
g_free(opt->value.stringval);
break;
case WTAP_OPTTYPE_CUSTOM:
opttype->free_func(opt->value.customval.data);
g_free(opt->value.customval.data);
break;
default:
break;
}
wtap_block_free_option(block, opt);
}
}
@ -837,6 +843,90 @@ wtap_block_set_custom_option_value(wtap_block_t block, guint option_id, void *va
return WTAP_OPTTYPE_SUCCESS;
}
wtap_opttype_return_val
wtap_block_remove_option(wtap_block_t block, guint option_id)
{
wtap_opttype_t *opttype;
guint i;
wtap_option_t *opt;
if (option_id >= block->info->options->len) {
/* There's no option for this block with that option ID */
return WTAP_OPTTYPE_NO_SUCH_OPTION;
}
opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
/*
* Can there be more than one instance of this option?
*/
if (opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED) {
/*
* Yes. You can't remove "the" value.
*/
return WTAP_OPTTYPE_NUMBER_MISMATCH;
}
for (i = 0; i < block->options->len; i++) {
opt = &g_array_index(block->options, wtap_option_t, i);
if (opt->option_id == option_id) {
/* Found it - free up the value */
wtap_block_free_option(block, opt);
/* Remove the option from the array of options */
g_array_remove_index(block->options, i);
return WTAP_OPTTYPE_SUCCESS;
}
}
/* Didn't find the option */
return WTAP_OPTTYPE_NOT_FOUND;
}
wtap_opttype_return_val
wtap_block_remove_nth_option_instance(wtap_block_t block, guint option_id,
guint idx)
{
wtap_opttype_t *opttype;
guint i;
wtap_option_t *opt;
guint opt_idx;
if (option_id >= block->info->options->len) {
/* There's no option for this block with that option ID */
return WTAP_OPTTYPE_NO_SUCH_OPTION;
}
opttype = &g_array_index(block->info->options, wtap_opttype_t, option_id);
/*
* Can there be more than one instance of this option?
*/
if (!(opttype->flags & WTAP_OPTTYPE_FLAG_MULTIPLE_ALLOWED)) {
/*
* No.
*/
return WTAP_OPTTYPE_NUMBER_MISMATCH;
}
opt_idx = 0;
for (i = 0; i < block->options->len; i++) {
opt = &g_array_index(block->options, wtap_option_t, i);
if (opt->option_id == option_id) {
if (opt_idx == idx) {
/* Found it - free up the value */
wtap_block_free_option(block, opt);
/* Remove the option from the array of options */
g_array_remove_index(block->options, i);
return WTAP_OPTTYPE_SUCCESS;
}
opt_idx++;
}
}
/* Didn't find the option */
return WTAP_OPTTYPE_NOT_FOUND;
}
static void shb_create(wtap_block_t block)
{
wtapng_mandatory_section_t* section_mand = g_new(wtapng_mandatory_section_t, 1);

View File

@ -481,6 +481,28 @@ wtap_block_set_custom_option_value(wtap_block_t block, guint option_id, void* va
WS_DLL_PUBLIC wtap_opttype_return_val
wtap_block_get_custom_option_value(wtap_block_t block, guint option_id, void** value) G_GNUC_WARN_UNUSED_RESULT;
/** Remove an option from a block
*
* @param[in] block Block from which to remove the option
* @param[in] option_id Identifier value for option
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
* error code otherwise
*/
WS_DLL_PUBLIC wtap_opttype_return_val
wtap_block_remove_option(wtap_block_t block, guint option_id);
/** Remove the nth instance of an option from a block
*
* @param[in] block Block from which to remove the option instance
* @param[in] option_id Identifier value for option
* @param[in] idx Instance number of option with that ID
* @return wtap_opttype_return_val - WTAP_OPTTYPE_SUCCESS if successful,
* error code otherwise
*/
WS_DLL_PUBLIC wtap_opttype_return_val
wtap_block_remove_nth_option_instance(wtap_block_t block, guint option_id,
guint idx);
/** Copy a block to another.
*
* Any options that are in the destination but not the source are not removed.