diff --git a/debian/libwireshark0.symbols b/debian/libwireshark0.symbols index 0ae7d2ed57..2481df98d8 100644 --- a/debian/libwireshark0.symbols +++ b/debian/libwireshark0.symbols @@ -658,6 +658,7 @@ libwireshark.so.0 libwireshark0 #MINVER# follow_iterate_followers@Base 2.1.0 follow_reset_stream@Base 2.1.0 follow_tvb_tap_listener@Base 2.1.0 + format_size_wmem@Base 3.3.0 format_text@Base 1.9.1 format_text_chr@Base 1.12.0~rc1 format_text_wsp@Base 1.9.1 diff --git a/epan/strutil.c b/epan/strutil.c index 72f921017d..2e9b47d69b 100644 --- a/epan/strutil.c +++ b/epan/strutil.c @@ -1657,6 +1657,15 @@ string_replace(const gchar* str, const gchar *old_val, const gchar *new_val) return new_str; } +gchar* +format_size_wmem(wmem_allocator_t *allocator, gint64 size, format_size_flags_e flags) +{ + gchar *str = format_size(size, flags); + gchar *ptr = wmem_strdup(allocator, str); + g_free(str); + return ptr; +} + /* * Editor modelines - https://www.wireshark.org/tools/modelines.html * diff --git a/epan/strutil.h b/epan/strutil.h index 2046cb0506..81a9dd2413 100644 --- a/epan/strutil.h +++ b/epan/strutil.h @@ -14,6 +14,7 @@ #include "ws_symbol_export.h" #include +#include #ifdef __cplusplus extern "C" { @@ -314,6 +315,24 @@ gchar* ws_strdup_unescape_char (const gchar *str, const gchar chr); WS_DLL_PUBLIC gchar *string_replace(const gchar* str, const gchar *old_val, const gchar *new_val); +/** +* format_size_wmem: +* Based on format_size (wsutil/str_util.h) +* +* Given a size, return its value in a human-readable format +* +* Prefixes up to "T/Ti" (tera, tebi) are currently supported. +* +* @param allocator An enumeration of the different types of available allocators. +* @param size The size value +* @param flags Flags to control the output (unit of measurement, +* SI vs IEC, etc). Unit, prefix and suffix flags may be ORed together. +* @return A newly-allocated string representing the value. +*/ +WS_DLL_PUBLIC +gchar* +format_size_wmem(wmem_allocator_t *allocator, gint64 size, format_size_flags_e flags); + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/wsutil/str_util.c b/wsutil/str_util.c index c03791dad5..5987317ba8 100644 --- a/wsutil/str_util.c +++ b/wsutil/str_util.c @@ -117,8 +117,9 @@ isdigit_string(const guchar *str) return TRUE; } -#define FORMAT_SIZE_UNIT_MASK 0x00ff -#define FORMAT_SIZE_PFX_MASK 0xff00 +#define FORMAT_SIZE_UNIT_MASK 0x0000ff +#define FORMAT_SIZE_PFX_MASK 0x00ff00 +#define FORMAT_SIZE_SFX_MASK 0xff0000 static const char *thousands_grouping_fmt = NULL; @@ -145,7 +146,8 @@ format_size(gint64 size, format_size_flags_e flags) int power = 1000; int pfx_off = 0; gboolean is_small = FALSE; - static const gchar *prefix[] = {" T", " G", " M", " k", " Ti", " Gi", " Mi", " Ki"}; + gboolean separate = ((flags & format_size_suffix_no_space) != format_size_suffix_no_space); + static const gchar *prefix[] = {"T", "G", "M", "k", "Ti", "Gi", "Mi", "Ki"}; gchar *ret_val; if (thousands_grouping_fmt == NULL) @@ -156,44 +158,51 @@ format_size(gint64 size, format_size_flags_e flags) power = 1024; } + if ((size / power >= 10) && separate) { + g_string_append_c(human_str, ' '); + } + if (size / power / power / power / power >= 10) { g_string_printf(human_str, thousands_grouping_fmt, size / power / power / power / power); - g_string_append(human_str, prefix[pfx_off]); + g_string_append_printf(human_str, "%s", prefix[pfx_off]); } else if (size / power / power / power >= 10) { g_string_printf(human_str, thousands_grouping_fmt, size / power / power / power); - g_string_append(human_str, prefix[pfx_off+1]); + g_string_append_printf(human_str, "%s", prefix[pfx_off+1]); } else if (size / power / power >= 10) { g_string_printf(human_str, thousands_grouping_fmt, size / power / power); - g_string_append(human_str, prefix[pfx_off+2]); + g_string_append_printf(human_str, "%s", prefix[pfx_off+2]); } else if (size / power >= 10) { g_string_printf(human_str, thousands_grouping_fmt, size / power); - g_string_append(human_str, prefix[pfx_off+3]); + g_string_append_printf(human_str, "%s", prefix[pfx_off+3]); } else { g_string_printf(human_str, thousands_grouping_fmt, size); is_small = TRUE; } + if ((flags & FORMAT_SIZE_UNIT_MASK) != format_size_unit_none && is_small && separate) { + g_string_append_c(human_str, ' '); + } switch (flags & FORMAT_SIZE_UNIT_MASK) { case format_size_unit_none: break; case format_size_unit_bytes: - g_string_append(human_str, is_small ? " bytes" : "B"); + g_string_append(human_str, is_small ? "bytes" : "B"); break; case format_size_unit_bits: - g_string_append(human_str, is_small ? " bits" : "b"); + g_string_append(human_str, is_small ? "bits" : "b"); break; case format_size_unit_bits_s: - g_string_append(human_str, is_small ? " bits/s" : "bps"); + g_string_append(human_str, is_small ? "bits/s" : "bps"); break; case format_size_unit_bytes_s: - g_string_append(human_str, is_small ? " bytes/s" : "Bps"); + g_string_append(human_str, is_small ? "bytes/s" : "Bps"); break; case format_size_unit_packets: - g_string_append(human_str, is_small ? " packets" : "packets"); + g_string_append(human_str, "packets"); break; case format_size_unit_packets_s: - g_string_append(human_str, is_small ? " packets/s" : "packets/s"); + g_string_append(human_str, "packets/s"); break; default: g_assert_not_reached(); diff --git a/wsutil/str_util.h b/wsutil/str_util.h index 9bdc82bdcd..95dc5ca599 100644 --- a/wsutil/str_util.h +++ b/wsutil/str_util.h @@ -91,7 +91,8 @@ typedef enum { format_size_unit_packets = 5, /**< "packets" */ format_size_unit_packets_s = 6, /**< "packets/s" */ format_size_prefix_si = 0 << 8, /**< SI (power of 1000) prefixes will be used. */ - format_size_prefix_iec = 1 << 8 /**< IEC (power of 1024) prefixes will be used. */ + format_size_prefix_iec = 1 << 8, /**< IEC (power of 1024) prefixes will be used. */ + format_size_suffix_no_space = 1 << 16 /**< Omit space between value and unit. */ /* XXX format_size_prefix_default_for_this_particular_os ? */ } format_size_flags_e; @@ -101,7 +102,7 @@ typedef enum { * * @param size The size value * @param flags Flags to control the output (unit of measurement, - * SI vs IEC, etc). Unit and prefix flags may be ORed together. + * SI vs IEC, etc). Unit, prefix and suffix flags may be ORed together. * @return A newly-allocated string representing the value. */ WS_DLL_PUBLIC