diff options
Diffstat (limited to 'vendor/github.com/dustin/go-humanize/bytes.go')
-rw-r--r-- | vendor/github.com/dustin/go-humanize/bytes.go | 143 |
1 files changed, 143 insertions, 0 deletions
diff --git a/vendor/github.com/dustin/go-humanize/bytes.go b/vendor/github.com/dustin/go-humanize/bytes.go new file mode 100644 index 0000000..0b498f4 --- /dev/null +++ b/vendor/github.com/dustin/go-humanize/bytes.go | |||
@@ -0,0 +1,143 @@ | |||
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 | } | ||