cubefs
189 строк · 4.7 Кб
1package humanize
2
3import (
4"fmt"
5"math/big"
6"strings"
7"unicode"
8)
9
10var (
11bigIECExp = big.NewInt(1024)
12
13// BigByte is one byte in bit.Ints
14BigByte = big.NewInt(1)
15// BigKiByte is 1,024 bytes in bit.Ints
16BigKiByte = (&big.Int{}).Mul(BigByte, bigIECExp)
17// BigMiByte is 1,024 k bytes in bit.Ints
18BigMiByte = (&big.Int{}).Mul(BigKiByte, bigIECExp)
19// BigGiByte is 1,024 m bytes in bit.Ints
20BigGiByte = (&big.Int{}).Mul(BigMiByte, bigIECExp)
21// BigTiByte is 1,024 g bytes in bit.Ints
22BigTiByte = (&big.Int{}).Mul(BigGiByte, bigIECExp)
23// BigPiByte is 1,024 t bytes in bit.Ints
24BigPiByte = (&big.Int{}).Mul(BigTiByte, bigIECExp)
25// BigEiByte is 1,024 p bytes in bit.Ints
26BigEiByte = (&big.Int{}).Mul(BigPiByte, bigIECExp)
27// BigZiByte is 1,024 e bytes in bit.Ints
28BigZiByte = (&big.Int{}).Mul(BigEiByte, bigIECExp)
29// BigYiByte is 1,024 z bytes in bit.Ints
30BigYiByte = (&big.Int{}).Mul(BigZiByte, bigIECExp)
31// BigRiByte is 1,024 y bytes in bit.Ints
32BigRiByte = (&big.Int{}).Mul(BigYiByte, bigIECExp)
33// BigQiByte is 1,024 r bytes in bit.Ints
34BigQiByte = (&big.Int{}).Mul(BigRiByte, bigIECExp)
35)
36
37var (
38bigSIExp = big.NewInt(1000)
39
40// BigSIByte is one SI byte in big.Ints
41BigSIByte = big.NewInt(1)
42// BigKByte is 1,000 SI bytes in big.Ints
43BigKByte = (&big.Int{}).Mul(BigSIByte, bigSIExp)
44// BigMByte is 1,000 SI k bytes in big.Ints
45BigMByte = (&big.Int{}).Mul(BigKByte, bigSIExp)
46// BigGByte is 1,000 SI m bytes in big.Ints
47BigGByte = (&big.Int{}).Mul(BigMByte, bigSIExp)
48// BigTByte is 1,000 SI g bytes in big.Ints
49BigTByte = (&big.Int{}).Mul(BigGByte, bigSIExp)
50// BigPByte is 1,000 SI t bytes in big.Ints
51BigPByte = (&big.Int{}).Mul(BigTByte, bigSIExp)
52// BigEByte is 1,000 SI p bytes in big.Ints
53BigEByte = (&big.Int{}).Mul(BigPByte, bigSIExp)
54// BigZByte is 1,000 SI e bytes in big.Ints
55BigZByte = (&big.Int{}).Mul(BigEByte, bigSIExp)
56// BigYByte is 1,000 SI z bytes in big.Ints
57BigYByte = (&big.Int{}).Mul(BigZByte, bigSIExp)
58// BigRByte is 1,000 SI y bytes in big.Ints
59BigRByte = (&big.Int{}).Mul(BigYByte, bigSIExp)
60// BigQByte is 1,000 SI r bytes in big.Ints
61BigQByte = (&big.Int{}).Mul(BigRByte, bigSIExp)
62)
63
64var bigBytesSizeTable = map[string]*big.Int{
65"b": BigByte,
66"kib": BigKiByte,
67"kb": BigKByte,
68"mib": BigMiByte,
69"mb": BigMByte,
70"gib": BigGiByte,
71"gb": BigGByte,
72"tib": BigTiByte,
73"tb": BigTByte,
74"pib": BigPiByte,
75"pb": BigPByte,
76"eib": BigEiByte,
77"eb": BigEByte,
78"zib": BigZiByte,
79"zb": BigZByte,
80"yib": BigYiByte,
81"yb": BigYByte,
82"rib": BigRiByte,
83"rb": BigRByte,
84"qib": BigQiByte,
85"qb": BigQByte,
86// Without suffix
87"": BigByte,
88"ki": BigKiByte,
89"k": BigKByte,
90"mi": BigMiByte,
91"m": BigMByte,
92"gi": BigGiByte,
93"g": BigGByte,
94"ti": BigTiByte,
95"t": BigTByte,
96"pi": BigPiByte,
97"p": BigPByte,
98"ei": BigEiByte,
99"e": BigEByte,
100"z": BigZByte,
101"zi": BigZiByte,
102"y": BigYByte,
103"yi": BigYiByte,
104"r": BigRByte,
105"ri": BigRiByte,
106"q": BigQByte,
107"qi": BigQiByte,
108}
109
110var ten = big.NewInt(10)
111
112func humanateBigBytes(s, base *big.Int, sizes []string) string {
113if s.Cmp(ten) < 0 {
114return fmt.Sprintf("%d B", s)
115}
116c := (&big.Int{}).Set(s)
117val, mag := oomm(c, base, len(sizes)-1)
118suffix := sizes[mag]
119f := "%.0f %s"
120if val < 10 {
121f = "%.1f %s"
122}
123
124return fmt.Sprintf(f, val, suffix)
125
126}
127
128// BigBytes produces a human readable representation of an SI size.
129//
130// See also: ParseBigBytes.
131//
132// BigBytes(82854982) -> 83 MB
133func BigBytes(s *big.Int) string {
134sizes := []string{"B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB", "RB", "QB"}
135return humanateBigBytes(s, bigSIExp, sizes)
136}
137
138// BigIBytes produces a human readable representation of an IEC size.
139//
140// See also: ParseBigBytes.
141//
142// BigIBytes(82854982) -> 79 MiB
143func BigIBytes(s *big.Int) string {
144sizes := []string{"B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB", "RiB", "QiB"}
145return humanateBigBytes(s, bigIECExp, sizes)
146}
147
148// ParseBigBytes parses a string representation of bytes into the number
149// of bytes it represents.
150//
151// See also: BigBytes, BigIBytes.
152//
153// ParseBigBytes("42 MB") -> 42000000, nil
154// ParseBigBytes("42 mib") -> 44040192, nil
155func ParseBigBytes(s string) (*big.Int, error) {
156lastDigit := 0
157hasComma := false
158for _, r := range s {
159if !(unicode.IsDigit(r) || r == '.' || r == ',') {
160break
161}
162if r == ',' {
163hasComma = true
164}
165lastDigit++
166}
167
168num := s[:lastDigit]
169if hasComma {
170num = strings.Replace(num, ",", "", -1)
171}
172
173val := &big.Rat{}
174_, err := fmt.Sscanf(num, "%f", val)
175if err != nil {
176return nil, err
177}
178
179extra := strings.ToLower(strings.TrimSpace(s[lastDigit:]))
180if m, ok := bigBytesSizeTable[extra]; ok {
181mv := (&big.Rat{}).SetInt(m)
182val.Mul(val, mv)
183rv := &big.Int{}
184rv.Div(val.Num(), val.Denom())
185return rv, nil
186}
187
188return nil, fmt.Errorf("unhandled size name: %v", extra)
189}
190