convtbl.c revision 164636
164439Scg/*
264439Scg * Copyright (c) 2003, Trent Nelson, <trent@arpa.com>.
364439Scg * All rights reserved.
464439Scg *
564439Scg * Redistribution and use in source and binary forms, with or without
664439Scg * modification, are permitted provided that the following conditions
764439Scg * are met:
864439Scg * 1. Redistributions of source code must retain the above copyright
964439Scg *    notice, this list of conditions and the following disclaimer.
1064439Scg * 2. Redistributions in binary form must reproduce the above copyright
1164439Scg *    notice, this list of conditions and the following disclaimer in the
1264439Scg *    documentation and/or other materials provided with the distribution.
1364439Scg * 3. The name of the author may not be used to endorse or promote products
1464439Scg *    derived from this software without specific prior written permission.
1564439Scg *
1664439Scg * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1764439Scg * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
1864439Scg * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
1964439Scg * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2064439Scg * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2164439Scg * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2264439Scg * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2364439Scg * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2464439Scg * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2564439Scg * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2664439Scg * SUCH DAMAGE.
2764439Scg *
2864439Scg * $FreeBSD: head/usr.bin/systat/convtbl.c 164636 2006-11-26 20:08:40Z yar $
2964439Scg */
3064439Scg
3164439Scg#include <sys/types.h>
3264439Scg#include <unistd.h>
3364439Scg#include "convtbl.h"
3464439Scg
3564439Scgstruct	convtbl convtbl[] = {
3664439Scg	/* mul, scale, str */
3764439Scg	{ BYTE, BYTES, "bytes" },	/* SC_BYTE	(0) */
3864439Scg	{ BYTE, KILO, "KB" },		/* SC_KILOBYTE	(1) */
3964439Scg	{ BYTE, MEGA, "MB" },		/* SC_MEGABYTE	(2) */
4064439Scg	{ BYTE, GIGA, "GB" },		/* SC_GIGABYTE	(3) */
4164439Scg
4264439Scg	{ BIT, BITS, "b" },		/* SC_BITS	(4) */
4364439Scg	{ BIT, KILO, "Kb" },		/* SC_KILOBITS	(5) */
4464439Scg	{ BIT, MEGA, "Mb" },		/* SC_MEGABITS	(6) */
45111898Sorion	{ BIT, GIGA, "Gb" },		/* SC_GIGABITS	(7) */
46111898Sorion
47112669Sorion	{ 0, 0, "" }			/* SC_AUTO	(8) */
48112669Sorion
49112669Sorion};
50111898Sorion
51111898Sorion
52111898Sorionstatic __inline
53111898Sorionstruct convtbl *
54111898Sorionget_tbl_ptr(const u_long size, const u_int scale)
55111898Sorion{
56111898Sorion	struct	convtbl *tbl_ptr = NULL;
57111898Sorion	u_long	tmp = 0;
58111898Sorion	u_int	idx = scale;
5964439Scg
6064439Scg	/* If our index is out of range, default to auto-scaling. */
61102010Sorion	if (idx > SC_AUTO)
62102010Sorion		idx = SC_AUTO;
6364439Scg
64102010Sorion	if (idx == SC_AUTO)
65102010Sorion		/*
6664439Scg		 * Simple but elegant algorithm.  Count how many times
6764439Scg		 * we can shift our size value right by a factor of ten,
68102010Sorion		 * incrementing an index each time.  We then use the
69102010Sorion		 * index as the array index into the conversion table.
7064439Scg		 */
7164439Scg		for (tmp = size, idx = SC_KILOBYTE;
7264439Scg		     tmp >= MEGA && idx < SC_GIGABYTE;
7364439Scg		     tmp >>= 10, idx++);
7464439Scg
75102010Sorion	tbl_ptr = &convtbl[idx];
76102010Sorion	return tbl_ptr;
77102010Sorion}
78102010Sorion
7964439Scgdouble
80102010Sorionconvert(const u_long size, const u_int scale)
8164439Scg{
8264439Scg	struct	convtbl	*tp = NULL;
8364439Scg
8464439Scg	tp = get_tbl_ptr(size, scale);
8564439Scg
8664439Scg	return ((double)size * tp->mul / tp->scale);
87
88}
89
90const char *
91get_string(const u_long size, const u_int scale)
92{
93	struct	convtbl *tp = NULL;
94
95	tp = get_tbl_ptr(size, scale);
96
97	return tp->str;
98}
99