diff --git a/print.c b/print.c index b41cd51e53..e032bcc72a 100644 --- a/print.c +++ b/print.c @@ -82,7 +82,7 @@ struct _output_fields { gchar aggregator; GPtrArray* fields; GHashTable* field_indicies; - emem_strbuf_t** field_values; + GPtrArray** field_values; gchar quote; gboolean includes_col_fields; }; @@ -780,6 +780,12 @@ write_carrays_finale(FILE *fh _U_) * Find the data source for a specified field, and return a pointer * to the data in it. Returns NULL if the data is out of bounds. */ +/* XXX: What am I missing ? + * Why bother searching for fi->ds_tvb for the matching tvb + * in the data_source list ? + * IOW: Why not just use fi->ds_tvb for the arg to tvb_get_ptr() ? + */ + static const guint8 * get_field_data(GSList *src_list, field_info *fi) { @@ -1354,6 +1360,14 @@ void output_fields_free(output_fields_t* fields) */ g_hash_table_destroy(fields->field_indicies); } + if(NULL != fields->field_values) { + gsize i; + for(i = 0; i < fields->fields->len; ++i) { + GPtrArray* fv_p; + fv_p = fields->field_values[i]; + g_ptr_array_free(fv_p, TRUE); + } + } if(NULL != fields->fields) { gsize i; for(i = 0; i < fields->fields->len; ++i) { @@ -1537,21 +1551,47 @@ void write_fields_preamble(output_fields_t* fields, FILE *fh) static void format_field_values(output_fields_t* fields, gpointer field_index, const gchar* value) { - if(NULL != value && '\0' != *value) { - guint actual_index; - actual_index = GPOINTER_TO_UINT(field_index); - /* Unwrap change made to disambiguiate zero / null */ - if (fields->field_values[actual_index - 1] == NULL ) { - fields->field_values[actual_index - 1] = ep_strbuf_new(value); - } else if (fields->occurrence == 'l' ) { - /* print only the value of the last occurrence of the field */ - ep_strbuf_printf(fields->field_values[actual_index - 1],"%s",value); - } else if (fields->occurrence == 'a' ) { - /* print the value of all accurrences of the field */ - ep_strbuf_append_printf(fields->field_values[actual_index - 1], - "%c%s",fields->aggregator,value); - } + guint index; + GPtrArray* fv_p; + + if (NULL == value || '\0' == *value) + return; + + /* Unwrap change made to disambiguiate zero / null */ + index = GPOINTER_TO_UINT(field_index) - 1; + + if (fields->field_values[index] == NULL) { + fields->field_values[index] = g_ptr_array_new(); } + + /* Essentially: fieldvalues[index] is an array of (ghar *) with each entry */ + /* pointing to a string which is (part of) the final output string. */ + + fv_p = fields->field_values[index]; + + switch (fields->occurrence) { + case 'f': + /* print the value of only the first occurrence of the field */ + if (g_ptr_array_len(fv_p) != 0) + return; + break; + case 'l': + /* print the value of only the last occurrence of the field */ + g_ptr_array_set_size(fv_p, 0); + break; + case 'a': + /* print the value of all accurrences of the field */ + /* If not the first, add the 'aggregator' */ + if (g_ptr_array_len(fv_p) > 0) { + g_ptr_array_add(fv_p, (gpointer)ep_strdup_printf("%c",fields->aggregator)); + } + break; + default: + g_assert_not_reached(); + break; + } + + g_ptr_array_add(fv_p, (gpointer)value); } static void proto_tree_get_node_field_values(proto_node *node, gpointer data) @@ -1569,7 +1609,7 @@ static void proto_tree_get_node_field_values(proto_node *node, gpointer data) field_index = g_hash_table_lookup(call_data->fields->field_indicies, fi->hfinfo->abbrev); if(NULL != field_index) { format_field_values(call_data->fields, field_index, - get_node_field_value(fi, call_data->edt) /* ep_alloced string */ + get_node_field_value(fi, call_data->edt) /* static or ep_alloc'd string */ ); } @@ -1611,8 +1651,8 @@ void proto_tree_write_fields(output_fields_t* fields, epan_dissect_t *edt, colum } } - /* Buffer to store values for this packet */ - fields->field_values = ep_alloc_array0(emem_strbuf_t*, fields->fields->len); + /* Array buffer to store values for this packet */ + fields->field_values = ep_alloc_array0(GPtrArray*, fields->fields->len); proto_tree_children_foreach(edt->tree, proto_tree_get_node_field_values, &data); @@ -1634,10 +1674,16 @@ void proto_tree_write_fields(output_fields_t* fields, epan_dissect_t *edt, colum fputc(fields->separator, fh); } if(NULL != fields->field_values[i]) { + GPtrArray *fv_p; + gsize j; + fv_p = fields->field_values[i]; if(fields->quote != '\0') { fputc(fields->quote, fh); } - fputs(fields->field_values[i]->str, fh); + + for (j = 0; j < g_ptr_array_len(fv_p); j++ ) { + fputs((gchar *)g_ptr_array_index(fv_p, j), fh); + } if(fields->quote != '\0') { fputc(fields->quote, fh); }