14
Byte = 1 << (iota * 10)
34
var bytesSizeTable = map[string]uint64{
64
func logn(n, b float64) float64 {
65
return math.Log(n) / math.Log(b)
68
func humanateBytes(s uint64, base float64, sizes []string) string {
70
return fmt.Sprintf("%dB", s)
72
e := math.Floor(logn(float64(s), base))
73
suffix := sizes[int(e)]
74
val := math.Floor(float64(s)/math.Pow(base, e)*10+0.5) / 10
80
return fmt.Sprintf(f, val, suffix)
83
// Bytes produces a human readable representation of an SI size.
85
// See also: ParseBytes.
87
// Bytes(82854982) -> 83MB
88
func Bytes(s uint64) string {
89
sizes := []string{"B", "KB", "MB", "GB", "TB", "PB", "EB"}
90
return humanateBytes(s, 1000, sizes)
93
// IBytes produces a human readable representation of an IEC size.
95
// See also: ParseBytes.
97
// IBytes(82854982) -> 79MiB
98
func IBytes(s uint64) string {
99
sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
100
return humanateBytes(s, 1024, sizes)
103
// ParseBytes parses a string representation of bytes into the number
104
// of bytes it represents.
106
// See Also: Bytes, IBytes.
108
// ParseBytes("42MB") -> 42000000, nil
109
// ParseBytes("42mib") -> 44040192, nil
110
func ParseBytes(s string) (uint64, error) {
112
for _, r := range s {
113
if !(unicode.IsDigit(r) || r == '.') {
119
f, err := strconv.ParseFloat(s[:lastDigit], 64)
124
extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
125
if m, ok := bytesSizeTable[extra]; ok {
127
if f >= math.MaxUint64 {
128
return 0, fmt.Errorf("too large: %v", s)
130
return uint64(f), nil
133
return 0, fmt.Errorf("unhandled size name: %v", extra)