Define all used storage units as constants. Use them in `DataSizeToUint64()`, instead of literal multiples.
90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"regexp"
|
|
"runtime"
|
|
"sort"
|
|
"strconv"
|
|
"strings"
|
|
)
|
|
|
|
var RuntimeGOARCH = runtime.GOARCH
|
|
|
|
func CurrentArch() string {
|
|
if RuntimeGOARCH == "amd64" {
|
|
return "x86_64"
|
|
} else if RuntimeGOARCH == "arm64" {
|
|
return "aarch64"
|
|
} else if RuntimeGOARCH == "ppc64le" {
|
|
return "ppc64le"
|
|
} else if RuntimeGOARCH == "s390x" {
|
|
return "s390x"
|
|
} else {
|
|
panic("unsupported architecture")
|
|
}
|
|
}
|
|
|
|
func PanicOnError(err error) {
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
}
|
|
|
|
// IsStringInSortedSlice returns true if the string is present, false if not
|
|
// slice must be sorted
|
|
func IsStringInSortedSlice(slice []string, s string) bool {
|
|
i := sort.SearchStrings(slice, s)
|
|
if i < len(slice) && slice[i] == s {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
// DataSizeToUint64 converts a size specified as a string in KB/KiB/MB/etc. to
|
|
// a number of bytes represented by uint64.
|
|
func DataSizeToUint64(size string) (uint64, error) {
|
|
// Pre-process the input
|
|
size = strings.TrimSpace(size)
|
|
|
|
// Get the number from the string
|
|
plain_number := regexp.MustCompile(`[[:digit:]]+`)
|
|
number_as_str := plain_number.FindString(size)
|
|
if number_as_str == "" {
|
|
return 0, fmt.Errorf("the size string doesn't contain any number: %s", size)
|
|
}
|
|
|
|
// Parse the number into integer
|
|
return_size, err := strconv.ParseUint(number_as_str, 10, 64)
|
|
if err != nil {
|
|
return 0, fmt.Errorf("failed to parse size as integer: %s", number_as_str)
|
|
}
|
|
|
|
// List of all supported units (from kB to TB and KiB to TiB)
|
|
supported_units := []struct {
|
|
re *regexp.Regexp
|
|
multiple uint64
|
|
}{
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*kB$`), KiloByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*KiB$`), KibiByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*MB$`), MegaByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*MiB$`), MebiByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*GB$`), GigaByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*GiB$`), GibiByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*TB$`), TeraByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+\s*TiB$`), TebiByte},
|
|
{regexp.MustCompile(`^\s*[[:digit:]]+$`), 1},
|
|
}
|
|
|
|
for _, unit := range supported_units {
|
|
if unit.re.MatchString(size) {
|
|
return_size *= unit.multiple
|
|
return return_size, nil
|
|
}
|
|
}
|
|
|
|
// In case the strign didn't match any of the above regexes, return nil
|
|
// even if a number was found. This is to prevent users from submitting
|
|
// unknown units.
|
|
return 0, fmt.Errorf("unknown data size units in string: %s", size)
|
|
}
|