Subject: format_bytes() [was part of allocsys() discussion]
To: None <tech-kern@netbsd.org>
From: Luke Mewburn <lukem@cs.rmit.edu.au>
List: tech-kern
Date: 05/09/1999 23:07:48
as part of my previous message about allocsys(), i provided a function
called format_memory() which formatted the memory display and returned
a pointer to a static buffer.

after a bit of feedback i've made this more generic. the result is:
	int format_bytes(char *buf, size_t len, u_int64_t bytes);

it takes bytes and snprintfs it into buf, after first dividing it
down so that it will fit into buf.

e.g, given len of 9, we get;

	bytes		result
	-----		------
	99999		`99999'
	100000		`97 KB'
	66715648	`65152 KB'
	252215296	`240 MB'

as suggested by Soren S. Jorvang, this function could be used in other
parts of the kernel to display stuff such as disk sizes, etc. 

here's the diff. (a prototype will be put in <sys/systm.h>).

any objections to this going in?


Index: kern_subr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/kern_subr.c,v
retrieving revision 1.47
diff -p -r1.47 kern_subr.c
*** kern_subr.c	1999/04/21 02:37:07	1.47
--- kern_subr.c	1999/05/09 13:06:08
***************
*** 1,12 ****
  /*	$NetBSD: kern_subr.c,v 1.47 1999/04/21 02:37:07 mrg Exp $	*/
  
  /*-
!  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
   * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
!  * NASA Ames Research Center.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
--- 1,12 ----
  /*	$NetBSD: kern_subr.c,v 1.47 1999/04/21 02:37:07 mrg Exp $	*/
  
  /*-
!  * Copyright (c) 1997, 1998, 1999 The NetBSD Foundation, Inc.
   * All rights reserved.
   *
   * This code is derived from software contributed to The NetBSD Foundation
   * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
!  * NASA Ames Research Center, and by Luke Mewburn.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
*************** getstr(cp, size)
*** 949,952 ****
--- 949,993 ----
  			*lp++ = c;
  		}
  	}
+ }
+ 
+ /*
+  * snprintf() `bytes' into `buf', reformatting it so that the number
+  * (plus a possible `xB' extension) fits into len bytes (including the
+  * terminating NUL).  Returns the number of bytes stored in buf, or -1
+  * if there was a problem.  E.g, given a len of 9: 
+  *	bytes		result
+  *	-----		------
+  *	99999		`99999'
+  *	100000		`97 KB'
+  *	66715648	`65152 KB'
+  *	252215296	`240 MB'
+  */
+ int
+ format_bytes(buf, len, bytes)
+ 	char		*buf;
+ 	size_t		 len;
+ 	u_int64_t	 bytes;
+ {
+ 		/* prefixes are: Kilo, Mega, Giga, Tera, Peta, Exa */
+ 	static const char prefixes[] = " KMGTPE";
+ 
+ 	int		i, r;
+ 	u_int64_t	max;
+ 
+ 	if (len > 0)
+ 		buf[0] = '\0';
+ 	if (len < 6)
+ 		return (-1);		/* not enough room for `xx yB\0' */
+ 
+ 	for (max = 1, i = 0; i < len - 4; i++)
+ 		max *= 10;
+ 	for (i = 0; bytes >= max && i < sizeof(prefixes); i++)
+ 		bytes /= 1024;
+ 
+ 	r = snprintf(buf, len, "%qd", (long long)bytes);
+ 	if (i > 0)
+ 		r += snprintf(buf + r, len - r, " %cB", prefixes[i]);
+ 
+ 	return (r);
  }