Blame lib/utils_math.c

Packit Bot 867fae
// SPDX-License-Identifier: GPL-2.0+
Packit Bot 867fae
Packit Bot 867fae
#include <stdio.h>
Packit Bot 867fae
#include <stdlib.h>
Packit Bot 867fae
#include <string.h>
Packit Bot 867fae
#include <math.h>
Packit Bot 867fae
#include <asm/types.h>
Packit Bot 867fae
Packit Bot 867fae
#include "utils.h"
Packit Bot 867fae
Packit Bot 867fae
/* See http://physics.nist.gov/cuu/Units/binary.html */
Packit Bot 867fae
static const struct rate_suffix {
Packit Bot 867fae
	const char *name;
Packit Bot 867fae
	double scale;
Packit Bot 867fae
} suffixes[] = {
Packit Bot 867fae
	{ "bit",	1. },
Packit Bot 867fae
	{ "Kibit",	1024. },
Packit Bot 867fae
	{ "kbit",	1000. },
Packit Bot 867fae
	{ "mibit",	1024.*1024. },
Packit Bot 867fae
	{ "mbit",	1000000. },
Packit Bot 867fae
	{ "gibit",	1024.*1024.*1024. },
Packit Bot 867fae
	{ "gbit",	1000000000. },
Packit Bot 867fae
	{ "tibit",	1024.*1024.*1024.*1024. },
Packit Bot 867fae
	{ "tbit",	1000000000000. },
Packit Bot 867fae
	{ "Bps",	8. },
Packit Bot 867fae
	{ "KiBps",	8.*1024. },
Packit Bot 867fae
	{ "KBps",	8000. },
Packit Bot 867fae
	{ "MiBps",	8.*1024*1024. },
Packit Bot 867fae
	{ "MBps",	8000000. },
Packit Bot 867fae
	{ "GiBps",	8.*1024.*1024.*1024. },
Packit Bot 867fae
	{ "GBps",	8000000000. },
Packit Bot 867fae
	{ "TiBps",	8.*1024.*1024.*1024.*1024. },
Packit Bot 867fae
	{ "TBps",	8000000000000. },
Packit Bot 867fae
	{ NULL }
Packit Bot 867fae
};
Packit Bot 867fae
Packit Bot 867fae
int get_rate(unsigned int *rate, const char *str)
Packit Bot 867fae
{
Packit Bot 867fae
	char *p;
Packit Bot 867fae
	double bps = strtod(str, &p);
Packit Bot 867fae
	const struct rate_suffix *s;
Packit Bot 867fae
Packit Bot 867fae
	if (p == str)
Packit Bot 867fae
		return -1;
Packit Bot 867fae
Packit Bot 867fae
	for (s = suffixes; s->name; ++s) {
Packit Bot 867fae
		if (strcasecmp(s->name, p) == 0) {
Packit Bot 867fae
			bps *= s->scale;
Packit Bot 867fae
			p += strlen(p);
Packit Bot 867fae
			break;
Packit Bot 867fae
		}
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	if (*p)
Packit Bot 867fae
		return -1; /* unknown suffix */
Packit Bot 867fae
Packit Bot 867fae
	bps /= 8; /* -> bytes per second */
Packit Bot 867fae
	*rate = bps;
Packit Bot 867fae
	/* detect if an overflow happened */
Packit Bot 867fae
	if (*rate != floor(bps))
Packit Bot 867fae
		return -1;
Packit Bot 867fae
	return 0;
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
int get_rate64(__u64 *rate, const char *str)
Packit Bot 867fae
{
Packit Bot 867fae
	char *p;
Packit Bot 867fae
	double bps = strtod(str, &p);
Packit Bot 867fae
	const struct rate_suffix *s;
Packit Bot 867fae
Packit Bot 867fae
	if (p == str)
Packit Bot 867fae
		return -1;
Packit Bot 867fae
Packit Bot 867fae
	for (s = suffixes; s->name; ++s) {
Packit Bot 867fae
		if (strcasecmp(s->name, p) == 0) {
Packit Bot 867fae
			bps *= s->scale;
Packit Bot 867fae
			p += strlen(p);
Packit Bot 867fae
			break;
Packit Bot 867fae
		}
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	if (*p)
Packit Bot 867fae
		return -1; /* unknown suffix */
Packit Bot 867fae
Packit Bot 867fae
	bps /= 8; /* -> bytes per second */
Packit Bot 867fae
	*rate = bps;
Packit Bot 867fae
	return 0;
Packit Bot 867fae
}
Packit Bot 867fae
Packit Bot 867fae
int get_size(unsigned int *size, const char *str)
Packit Bot 867fae
{
Packit Bot 867fae
	double sz;
Packit Bot 867fae
	char *p;
Packit Bot 867fae
Packit Bot 867fae
	sz = strtod(str, &p);
Packit Bot 867fae
	if (p == str)
Packit Bot 867fae
		return -1;
Packit Bot 867fae
Packit Bot 867fae
	if (*p) {
Packit Bot 867fae
		if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0)
Packit Bot 867fae
			sz *= 1024;
Packit Bot 867fae
		else if (strcasecmp(p, "gb") == 0 || strcasecmp(p, "g") == 0)
Packit Bot 867fae
			sz *= 1024*1024*1024;
Packit Bot 867fae
		else if (strcasecmp(p, "gbit") == 0)
Packit Bot 867fae
			sz *= 1024*1024*1024/8;
Packit Bot 867fae
		else if (strcasecmp(p, "mb") == 0 || strcasecmp(p, "m") == 0)
Packit Bot 867fae
			sz *= 1024*1024;
Packit Bot 867fae
		else if (strcasecmp(p, "mbit") == 0)
Packit Bot 867fae
			sz *= 1024*1024/8;
Packit Bot 867fae
		else if (strcasecmp(p, "kbit") == 0)
Packit Bot 867fae
			sz *= 1024/8;
Packit Bot 867fae
		else if (strcasecmp(p, "b") != 0)
Packit Bot 867fae
			return -1;
Packit Bot 867fae
	}
Packit Bot 867fae
Packit Bot 867fae
	*size = sz;
Packit Bot 867fae
Packit Bot 867fae
	/* detect if an overflow happened */
Packit Bot 867fae
	if (*size != floor(sz))
Packit Bot 867fae
		return -1;
Packit Bot 867fae
Packit Bot 867fae
	return 0;
Packit Bot 867fae
}