mirror of https://github.com/k3s-io/k3s
163 lines
3.7 KiB
Go
163 lines
3.7 KiB
Go
|
package units
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strconv"
|
||
|
)
|
||
|
|
||
|
// ParseByteSizeString parses a human representation of an amount of
|
||
|
// data into a number of bytes
|
||
|
func ParseByteSizeString(input string) (int64, error) {
|
||
|
// Empty input
|
||
|
if input == "" {
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
// Find where the suffix begins
|
||
|
suffixLen := 0
|
||
|
for i, chr := range []byte(input) {
|
||
|
_, err := strconv.Atoi(string([]byte{chr}))
|
||
|
if err != nil {
|
||
|
suffixLen = len(input) - i
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if suffixLen == len(input) {
|
||
|
return -1, fmt.Errorf("Invalid value: %s", input)
|
||
|
}
|
||
|
|
||
|
// Extract the suffix
|
||
|
suffix := input[len(input)-suffixLen:]
|
||
|
|
||
|
// Extract the value
|
||
|
value := input[0 : len(input)-suffixLen]
|
||
|
valueInt, err := strconv.ParseInt(value, 10, 64)
|
||
|
if err != nil {
|
||
|
return -1, fmt.Errorf("Invalid integer: %s", input)
|
||
|
}
|
||
|
|
||
|
// Figure out the multiplicator
|
||
|
multiplicator := int64(0)
|
||
|
switch suffix {
|
||
|
case "", "B", " bytes":
|
||
|
multiplicator = 1
|
||
|
case "kB":
|
||
|
multiplicator = 1000
|
||
|
case "MB":
|
||
|
multiplicator = 1000 * 1000
|
||
|
case "GB":
|
||
|
multiplicator = 1000 * 1000 * 1000
|
||
|
case "TB":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000
|
||
|
case "PB":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
|
||
|
case "EB":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
|
||
|
case "KiB":
|
||
|
multiplicator = 1024
|
||
|
case "MiB":
|
||
|
multiplicator = 1024 * 1024
|
||
|
case "GiB":
|
||
|
multiplicator = 1024 * 1024 * 1024
|
||
|
case "TiB":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024
|
||
|
case "PiB":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
|
||
|
case "EiB":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
|
||
|
default:
|
||
|
return -1, fmt.Errorf("Invalid value: %s", input)
|
||
|
}
|
||
|
|
||
|
return valueInt * multiplicator, nil
|
||
|
}
|
||
|
|
||
|
// ParseBitSizeString parses a human representation of an amount of
|
||
|
// data into a number of bits
|
||
|
func ParseBitSizeString(input string) (int64, error) {
|
||
|
// Empty input
|
||
|
if input == "" {
|
||
|
return 0, nil
|
||
|
}
|
||
|
|
||
|
// Find where the suffix begins
|
||
|
suffixLen := 0
|
||
|
for i, chr := range []byte(input) {
|
||
|
_, err := strconv.Atoi(string([]byte{chr}))
|
||
|
if err != nil {
|
||
|
suffixLen = len(input) - i
|
||
|
break
|
||
|
}
|
||
|
}
|
||
|
|
||
|
if suffixLen == len(input) {
|
||
|
return -1, fmt.Errorf("Invalid value: %s", input)
|
||
|
}
|
||
|
|
||
|
// Extract the suffix
|
||
|
suffix := input[len(input)-suffixLen:]
|
||
|
|
||
|
// Extract the value
|
||
|
value := input[0 : len(input)-suffixLen]
|
||
|
valueInt, err := strconv.ParseInt(value, 10, 64)
|
||
|
if err != nil {
|
||
|
return -1, fmt.Errorf("Invalid integer: %s", input)
|
||
|
}
|
||
|
|
||
|
// Figure out the multiplicator
|
||
|
multiplicator := int64(0)
|
||
|
switch suffix {
|
||
|
case "", "bit":
|
||
|
multiplicator = 1
|
||
|
case "kbit":
|
||
|
multiplicator = 1000
|
||
|
case "Mbit":
|
||
|
multiplicator = 1000 * 1000
|
||
|
case "Gbit":
|
||
|
multiplicator = 1000 * 1000 * 1000
|
||
|
case "Tbit":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000
|
||
|
case "Pbit":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000 * 1000
|
||
|
case "Ebit":
|
||
|
multiplicator = 1000 * 1000 * 1000 * 1000 * 1000 * 1000
|
||
|
case "Kibit":
|
||
|
multiplicator = 1024
|
||
|
case "Mibit":
|
||
|
multiplicator = 1024 * 1024
|
||
|
case "Gibit":
|
||
|
multiplicator = 1024 * 1024 * 1024
|
||
|
case "Tibit":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024
|
||
|
case "Pibit":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024 * 1024
|
||
|
case "Eibit":
|
||
|
multiplicator = 1024 * 1024 * 1024 * 1024 * 1024 * 1024
|
||
|
|
||
|
default:
|
||
|
return -1, fmt.Errorf("Unsupported suffix: %s", suffix)
|
||
|
}
|
||
|
|
||
|
return valueInt * multiplicator, nil
|
||
|
}
|
||
|
|
||
|
// GetByteSizeString takes a number of bytes and precision and returns a
|
||
|
// human representation of the amount of data
|
||
|
func GetByteSizeString(input int64, precision uint) string {
|
||
|
if input < 1000 {
|
||
|
return fmt.Sprintf("%dB", input)
|
||
|
}
|
||
|
|
||
|
value := float64(input)
|
||
|
|
||
|
for _, unit := range []string{"kB", "MB", "GB", "TB", "PB", "EB"} {
|
||
|
value = value / 1000
|
||
|
if value < 1000 {
|
||
|
return fmt.Sprintf("%.*f%s", precision, value, unit)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return fmt.Sprintf("%.*fEB", precision, value)
|
||
|
}
|