aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuy Harris <guy@alum.mit.edu>2016-07-15 17:25:41 -0700
committerGuy Harris <guy@alum.mit.edu>2016-07-16 00:26:47 +0000
commitae598d17370e141c37e3130fe16123d3e36d5195 (patch)
treebaf8f4011b5e67aa97954d1e34f891a904ea9f97
parent9dd2674fada1f1b8cfed521b5ee4c3a4852a7ef9 (diff)
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>
-rw-r--r--wiretap/wtap_opttypes.c122
-rw-r--r--wiretap/wtap_opttypes.h22
2 files changed, 128 insertions, 16 deletions
diff --git a/wiretap/wtap_opttypes.c b/wiretap/wtap_opttypes.c
index 0f4da0f936..c3b9f0df29 100644
--- a/wiretap/wtap_opttypes.c
+++ b/wiretap/wtap_opttypes.c
@@ -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);
diff --git a/wiretap/wtap_opttypes.h b/wiretap/wtap_opttypes.h
index a7d2fe8966..f1c4fd3af3 100644
--- a/wiretap/wtap_opttypes.h
+++ b/wiretap/wtap_opttypes.h
@@ -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.