diff --git a/MemoryMeter.c b/MemoryMeter.c index f1c1e357..ba9dcc9c 100644 --- a/MemoryMeter.c +++ b/MemoryMeter.c @@ -25,8 +25,16 @@ int MemoryMeter_attributes[] = { }; static void MemoryMeter_setValues(Meter* this, char* buffer, int size) { + int written; Platform_setMemoryValues(this); - snprintf(buffer, size, "%ld/%ldM", (long int) this->values[0] / 1024, (long int) this->total / 1024); + + written = Meter_humanUnit(buffer, this->values[0], size); + buffer += written; + if ((size -= written) > 0) { + *buffer++ = '/'; + size--; + Meter_humanUnit(buffer, this->total, size); + } } static void MemoryMeter_display(Object* cast, RichString* out) { diff --git a/Meter.c b/Meter.c index cc661e6a..732203f9 100644 --- a/Meter.c +++ b/Meter.c @@ -141,6 +141,34 @@ Meter* Meter_new(struct ProcessList_* pl, int param, MeterClass* type) { return this; } +int Meter_humanUnit(char* buffer, unsigned long int value, int size) { + const char * prefix = "KMGTPEZY"; + unsigned long int powi = 1; + unsigned int written, powj = 1, precision = 2; + + for(;;) { + if (value / 1024 < powi) + break; + + if (prefix[1] == 0) + break; + + powi *= 1024; + ++prefix; + } + + for (; precision > 0; precision--) { + powj *= 10; + if (value / powi < powj) + break; + } + + written = snprintf(buffer, size, "%.*f%c", + precision, (double) value / powi, *prefix); + + return written; +} + void Meter_delete(Object* cast) { if (!cast) return; diff --git a/Meter.h b/Meter.h index 6b268c3f..fe102fb3 100644 --- a/Meter.h +++ b/Meter.h @@ -105,6 +105,8 @@ extern MeterClass Meter_class; Meter* Meter_new(struct ProcessList_* pl, int param, MeterClass* type); +int Meter_humanUnit(char* buffer, unsigned long int value, int size); + void Meter_delete(Object* cast); void Meter_setCaption(Meter* this, const char* caption); diff --git a/SwapMeter.c b/SwapMeter.c index a19c0300..aaa5e93c 100644 --- a/SwapMeter.c +++ b/SwapMeter.c @@ -33,9 +33,17 @@ static void SwapMeter_humanNumber(char* buffer, const long int* value) { sprintf(buffer, "%ldM ", *value / MEGABYTE); } -static void SwapMeter_setValues(Meter* this, char* buffer, int len) { +static void SwapMeter_setValues(Meter* this, char* buffer, int size) { + int written; Platform_setSwapValues(this); - snprintf(buffer, len, "%ld/%ldM", (long int) this->values[0] / MEGABYTE, (long int) this->total / MEGABYTE); + + written = Meter_humanUnit(buffer, this->values[0], size); + buffer += written; + if ((size -= written) > 0) { + *buffer++ = '/'; + size--; + Meter_humanUnit(buffer, this->total, size); + } } static void SwapMeter_display(Object* cast, RichString* out) {