1108684Sphk/* 2108684Sphk * Copyright (c) 2003, Trent Nelson, <trent@arpa.com>. 3108684Sphk * All rights reserved. 4108684Sphk * 5108684Sphk * Redistribution and use in source and binary forms, with or without 6108684Sphk * modification, are permitted provided that the following conditions 7108684Sphk * are met: 8108684Sphk * 1. Redistributions of source code must retain the above copyright 9108684Sphk * notice, this list of conditions and the following disclaimer. 10108684Sphk * 2. Redistributions in binary form must reproduce the above copyright 11108684Sphk * notice, this list of conditions and the following disclaimer in the 12108684Sphk * documentation and/or other materials provided with the distribution. 13108684Sphk * 3. The name of the author may not be used to endorse or promote products 14108684Sphk * derived from this software without specific prior written permission. 15108684Sphk * 16108684Sphk * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17108684Sphk * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18108684Sphk * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19108684Sphk * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20108684Sphk * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21108684Sphk * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22108684Sphk * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23108684Sphk * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24108684Sphk * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25108684Sphk * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26108684Sphk * SUCH DAMAGE. 27108684Sphk * 28108684Sphk * $FreeBSD: releng/10.2/usr.bin/systat/convtbl.c 175387 2008-01-16 19:27:43Z delphij $ 29108684Sphk */ 30108684Sphk 31108684Sphk#include <sys/types.h> 32164672Syar#include <stdlib.h> 33164672Syar#include <string.h> 34108684Sphk#include "convtbl.h" 35108684Sphk 36166084Sru#define BIT (8) 37166084Sru#define BITS (1) 38166084Sru#define KILOBIT (1000LL) 39166084Sru#define MEGABIT (KILOBIT * 1000) 40166084Sru#define GIGABIT (MEGABIT * 1000) 41166084Sru#define TERABIT (GIGABIT * 1000) 42164673Syar 43166084Sru#define BYTE (1) 44166084Sru#define BYTES (1) 45166084Sru#define KILOBYTE (1024LL) 46166084Sru#define MEGABYTE (KILOBYTE * 1024) 47166084Sru#define GIGABYTE (MEGABYTE * 1024) 48166084Sru#define TERABYTE (GIGABYTE * 1024) 49164673Syar 50164673Syarstruct convtbl { 51164673Syar uintmax_t mul; 52164673Syar uintmax_t scale; 53164673Syar const char *str; 54164673Syar const char *name; 55164673Syar}; 56164673Syar 57164673Syarstatic struct convtbl convtbl[] = { 58164672Syar /* mul, scale, str, name */ 59166084Sru [SC_BYTE] = { BYTE, BYTES, "B", "byte" }, 60166084Sru [SC_KILOBYTE] = { BYTE, KILOBYTE, "KB", "kbyte" }, 61166084Sru [SC_MEGABYTE] = { BYTE, MEGABYTE, "MB", "mbyte" }, 62166084Sru [SC_GIGABYTE] = { BYTE, GIGABYTE, "GB", "gbyte" }, 63166084Sru [SC_TERABYTE] = { BYTE, TERABYTE, "TB", "tbyte" }, 64108684Sphk 65166084Sru [SC_BIT] = { BIT, BITS, "b", "bit" }, 66166084Sru [SC_KILOBIT] = { BIT, KILOBIT, "Kb", "kbit" }, 67166084Sru [SC_MEGABIT] = { BIT, MEGABIT, "Mb", "mbit" }, 68166084Sru [SC_GIGABIT] = { BIT, GIGABIT, "Gb", "gbit" }, 69166084Sru [SC_TERABIT] = { BIT, TERABIT, "Tb", "tbit" }, 70108684Sphk 71164672Syar [SC_AUTO] = { 0, 0, "", "auto" } 72108684Sphk}; 73108684Sphk 74164637Syarstatic 75108684Sphkstruct convtbl * 76164671Syarget_tbl_ptr(const uintmax_t size, const int scale) 77108684Sphk{ 78164671Syar uintmax_t tmp; 79164671Syar int idx; 80108684Sphk 81108684Sphk /* If our index is out of range, default to auto-scaling. */ 82164669Syar idx = scale < SC_AUTO ? scale : SC_AUTO; 83108684Sphk 84126775Sdwmalone if (idx == SC_AUTO) 85108684Sphk /* 86108684Sphk * Simple but elegant algorithm. Count how many times 87108684Sphk * we can shift our size value right by a factor of ten, 88108684Sphk * incrementing an index each time. We then use the 89108684Sphk * index as the array index into the conversion table. 90108684Sphk */ 91126775Sdwmalone for (tmp = size, idx = SC_KILOBYTE; 92166084Sru tmp >= MEGABYTE && idx < SC_BIT - 1; 93126775Sdwmalone tmp >>= 10, idx++); 94108684Sphk 95164669Syar return (&convtbl[idx]); 96108684Sphk} 97108684Sphk 98108684Sphkdouble 99164671Syarconvert(const uintmax_t size, const int scale) 100108684Sphk{ 101164669Syar struct convtbl *tp; 102108684Sphk 103108684Sphk tp = get_tbl_ptr(size, scale); 104108684Sphk return ((double)size * tp->mul / tp->scale); 105108684Sphk 106108684Sphk} 107108684Sphk 108126775Sdwmaloneconst char * 109164671Syarget_string(const uintmax_t size, const int scale) 110108684Sphk{ 111164669Syar struct convtbl *tp; 112108684Sphk 113108684Sphk tp = get_tbl_ptr(size, scale); 114164669Syar return (tp->str); 115108684Sphk} 116164672Syar 117164672Syarint 118164672Syarget_scale(const char *name) 119164672Syar{ 120164672Syar int i; 121164672Syar 122164672Syar for (i = 0; i <= SC_AUTO; i++) 123164672Syar if (strcmp(convtbl[i].name, name) == 0) 124164672Syar return (i); 125164672Syar return (-1); 126164672Syar} 127164672Syar 128164672Syarconst char * 129175387Sdelphijget_helplist(void) 130164672Syar{ 131164672Syar int i; 132164672Syar size_t len; 133164672Syar static char *buf; 134164672Syar 135164672Syar if (buf == NULL) { 136164672Syar len = 0; 137164672Syar for (i = 0; i <= SC_AUTO; i++) 138164672Syar len += strlen(convtbl[i].name) + 2; 139164672Syar if ((buf = malloc(len)) != NULL) { 140164672Syar buf[0] = '\0'; 141164672Syar for (i = 0; i <= SC_AUTO; i++) { 142164672Syar strcat(buf, convtbl[i].name); 143164672Syar if (i < SC_AUTO) 144164672Syar strcat(buf, ", "); 145164672Syar } 146164672Syar } else 147164672Syar return (""); 148164672Syar } 149164672Syar return (buf); 150164672Syar} 151