cubefs

Форк
0
143 строки · 2.5 Кб
1
package humanize
2

3
import (
4
	"fmt"
5
	"math"
6
	"strconv"
7
	"strings"
8
	"unicode"
9
)
10

11
// IEC Sizes.
12
// kibis of bits
13
const (
14
	Byte = 1 << (iota * 10)
15
	KiByte
16
	MiByte
17
	GiByte
18
	TiByte
19
	PiByte
20
	EiByte
21
)
22

23
// SI Sizes.
24
const (
25
	IByte = 1
26
	KByte = IByte * 1000
27
	MByte = KByte * 1000
28
	GByte = MByte * 1000
29
	TByte = GByte * 1000
30
	PByte = TByte * 1000
31
	EByte = PByte * 1000
32
)
33

34
var bytesSizeTable = map[string]uint64{
35
	"b":   Byte,
36
	"kib": KiByte,
37
	"kb":  KByte,
38
	"mib": MiByte,
39
	"mb":  MByte,
40
	"gib": GiByte,
41
	"gb":  GByte,
42
	"tib": TiByte,
43
	"tb":  TByte,
44
	"pib": PiByte,
45
	"pb":  PByte,
46
	"eib": EiByte,
47
	"eb":  EByte,
48
	// Without suffix
49
	"":   Byte,
50
	"ki": KiByte,
51
	"k":  KByte,
52
	"mi": MiByte,
53
	"m":  MByte,
54
	"gi": GiByte,
55
	"g":  GByte,
56
	"ti": TiByte,
57
	"t":  TByte,
58
	"pi": PiByte,
59
	"p":  PByte,
60
	"ei": EiByte,
61
	"e":  EByte,
62
}
63

64
func logn(n, b float64) float64 {
65
	return math.Log(n) / math.Log(b)
66
}
67

68
func humanateBytes(s uint64, base float64, sizes []string) string {
69
	if s < 10 {
70
		return fmt.Sprintf("%d B", s)
71
	}
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
75
	f := "%.0f %s"
76
	if val < 10 {
77
		f = "%.1f %s"
78
	}
79

80
	return fmt.Sprintf(f, val, suffix)
81
}
82

83
// Bytes produces a human readable representation of an SI size.
84
//
85
// See also: ParseBytes.
86
//
87
// Bytes(82854982) -> 83 MB
88
func Bytes(s uint64) string {
89
	sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB"}
90
	return humanateBytes(s, 1000, sizes)
91
}
92

93
// IBytes produces a human readable representation of an IEC size.
94
//
95
// See also: ParseBytes.
96
//
97
// IBytes(82854982) -> 79 MiB
98
func IBytes(s uint64) string {
99
	sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB"}
100
	return humanateBytes(s, 1024, sizes)
101
}
102

103
// ParseBytes parses a string representation of bytes into the number
104
// of bytes it represents.
105
//
106
// See Also: Bytes, IBytes.
107
//
108
// ParseBytes("42 MB") -> 42000000, nil
109
// ParseBytes("42 mib") -> 44040192, nil
110
func ParseBytes(s string) (uint64, error) {
111
	lastDigit := 0
112
	hasComma := false
113
	for _, r := range s {
114
		if !(unicode.IsDigit(r) || r == '.' || r == ',') {
115
			break
116
		}
117
		if r == ',' {
118
			hasComma = true
119
		}
120
		lastDigit++
121
	}
122

123
	num := s[:lastDigit]
124
	if hasComma {
125
		num = strings.Replace(num, ",", "", -1)
126
	}
127

128
	f, err := strconv.ParseFloat(num, 64)
129
	if err != nil {
130
		return 0, err
131
	}
132

133
	extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
134
	if m, ok := bytesSizeTable[extra]; ok {
135
		f *= float64(m)
136
		if f >= math.MaxUint64 {
137
			return 0, fmt.Errorf("too large: %v", s)
138
		}
139
		return uint64(f), nil
140
	}
141

142
	return 0, fmt.Errorf("unhandled size name: %v", extra)
143
}
144

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.