/* * Copyright 2003, 2005 Bernhard Walle * ------------------------------------------------------------------------------------------------- * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., 675 Mass * Ave, Cambridge, MA 02139, USA. * * ------------------------------------------------------------------------------------------------- */ #include #include #include #include #include #include #include #ifdef HAVE_CONFIG_H #include #endif #ifndef BUFSIZ #define BUFSIZ 512 #endif /* ---------------------------------------------------------------------------------------------- */ unsigned long min_array( unsigned long array[], int size ) { int i; unsigned long min = array[0]; for (i = 1; i < size; i++) { if (array[i] < min) { min = array[i]; } } return min; } /* ---------------------------------------------------------------------------------------------- */ unsigned long max_array( unsigned long array[], int size ) { int i; unsigned long max = array[0]; for (i = 1; i < size; i++) { if( array[i] > max ) { max = array[i]; } } return max; } /* ---------------------------------------------------------------------------------------------- */ char* format_byte_humanreadable(char* string, int stringsize, double number, int digits, gboolean as_bits) { char* str = string; char buffer[BUFSIZ], formatstring[BUFSIZ]; char* bufptr = buffer; char* unit_names[] = { N_("B"), N_("KiB"), N_("MiB"), N_("GiB") }; char* unit_names_bits[] = { N_("bps"), N_("Kbps"), N_("Mbps"), N_("Gbps") }; unsigned int uidx = 0; double number_displayed = 0; double thousand_divider = as_bits ? 1000 : 1024; unsigned int i; int numberOfIntegerChars, count; struct lconv* localeinfo = localeconv(); int grouping = (int)localeinfo->grouping[0] == 0 ? INT_MAX : (int)localeinfo->grouping[0]; /* Start with kilo and adapt to bits values*/ uidx = 1; number_displayed = number / thousand_divider; if (as_bits) { number_displayed *= 8; } /* sensible value for digits */ if (digits < 0 || digits >= 10) { digits = 2; } /* 1 digit for values above MiB/s unit size */ if (digits > 1 && number_displayed > thousand_divider * thousand_divider) { digits = 1; } /* calculate number and appropriate unit size for display */ while(number_displayed >= thousand_divider && uidx < (sizeof(unit_names) / sizeof(char*) - 1)) { number_displayed /= thousand_divider; uidx++; } /* format number first */ snprintf(formatstring, BUFSIZ, "%%.%df", digits); snprintf(buffer, BUFSIZ, formatstring, number_displayed); /* get the number of integer characters */ count = numberOfIntegerChars = ( digits > 0 ? ( strstr( buffer, localeinfo->decimal_point ) - buffer ) : strlen( buffer ) ); /* check for length */ if( numberOfIntegerChars / grouping + (int)strlen( buffer ) > stringsize ) { return NULL; } /* insert the thousands separator */ while (*bufptr != 0 && *bufptr != localeinfo->decimal_point[0]) { if (count % grouping == 0 && count != numberOfIntegerChars) { for (i = 0; i < strlen( localeinfo->thousands_sep ); i++) { *str++ = localeinfo->thousands_sep[i]; } } *str++ = *bufptr++; count--; } /* Copy the rest of the number */ while (digits > 0 && *bufptr != 0) { *str++ = *bufptr++; } /* Add space */ *str++ = ' '; /* terminate with 0 finally */ *str = 0; /* Add the unit name */ g_strlcat(string, as_bits ? _(unit_names_bits[uidx]) : _(unit_names[uidx]), stringsize); return string; }