iproute2/lib/utils_math.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+
   2
   3#include <stdio.h>
   4#include <stdlib.h>
   5#include <string.h>
   6#include <math.h>
   7#include <asm/types.h>
   8
   9#include "utils.h"
  10
  11/* See http://physics.nist.gov/cuu/Units/binary.html */
  12static const struct rate_suffix {
  13        const char *name;
  14        double scale;
  15} suffixes[] = {
  16        { "bit",        1. },
  17        { "Kibit",      1024. },
  18        { "kbit",       1000. },
  19        { "mibit",      1024.*1024. },
  20        { "mbit",       1000000. },
  21        { "gibit",      1024.*1024.*1024. },
  22        { "gbit",       1000000000. },
  23        { "tibit",      1024.*1024.*1024.*1024. },
  24        { "tbit",       1000000000000. },
  25        { "Bps",        8. },
  26        { "KiBps",      8.*1024. },
  27        { "KBps",       8000. },
  28        { "MiBps",      8.*1024*1024. },
  29        { "MBps",       8000000. },
  30        { "GiBps",      8.*1024.*1024.*1024. },
  31        { "GBps",       8000000000. },
  32        { "TiBps",      8.*1024.*1024.*1024.*1024. },
  33        { "TBps",       8000000000000. },
  34        { NULL }
  35};
  36
  37int get_rate(unsigned int *rate, const char *str)
  38{
  39        char *p;
  40        double bps = strtod(str, &p);
  41        const struct rate_suffix *s;
  42
  43        if (p == str)
  44                return -1;
  45
  46        for (s = suffixes; s->name; ++s) {
  47                if (strcasecmp(s->name, p) == 0) {
  48                        bps *= s->scale;
  49                        p += strlen(p);
  50                        break;
  51                }
  52        }
  53
  54        if (*p)
  55                return -1; /* unknown suffix */
  56
  57        bps /= 8; /* -> bytes per second */
  58        *rate = bps;
  59        /* detect if an overflow happened */
  60        if (*rate != floor(bps))
  61                return -1;
  62        return 0;
  63}
  64
  65int get_rate64(__u64 *rate, const char *str)
  66{
  67        char *p;
  68        double bps = strtod(str, &p);
  69        const struct rate_suffix *s;
  70
  71        if (p == str)
  72                return -1;
  73
  74        for (s = suffixes; s->name; ++s) {
  75                if (strcasecmp(s->name, p) == 0) {
  76                        bps *= s->scale;
  77                        p += strlen(p);
  78                        break;
  79                }
  80        }
  81
  82        if (*p)
  83                return -1; /* unknown suffix */
  84
  85        bps /= 8; /* -> bytes per second */
  86        *rate = bps;
  87        return 0;
  88}
  89
  90int get_size(unsigned int *size, const char *str)
  91{
  92        double sz;
  93        char *p;
  94
  95        sz = strtod(str, &p);
  96        if (p == str)
  97                return -1;
  98
  99        if (*p) {
 100                if (strcasecmp(p, "kb") == 0 || strcasecmp(p, "k") == 0)
 101                        sz *= 1024;
 102                else if (strcasecmp(p, "gb") == 0 || strcasecmp(p, "g") == 0)
 103                        sz *= 1024*1024*1024;
 104                else if (strcasecmp(p, "gbit") == 0)
 105                        sz *= 1024*1024*1024/8;
 106                else if (strcasecmp(p, "mb") == 0 || strcasecmp(p, "m") == 0)
 107                        sz *= 1024*1024;
 108                else if (strcasecmp(p, "mbit") == 0)
 109                        sz *= 1024*1024/8;
 110                else if (strcasecmp(p, "kbit") == 0)
 111                        sz *= 1024/8;
 112                else if (strcasecmp(p, "b") != 0)
 113                        return -1;
 114        }
 115
 116        *size = sz;
 117
 118        /* detect if an overflow happened */
 119        if (*size != floor(sz))
 120                return -1;
 121
 122        return 0;
 123}
 124