1package units
2
3// Base2Bytes is the old non-SI power-of-2 byte scale (1024 bytes in a kilobyte,
4// etc.).
5type Base2Bytes int64
6
7// Base-2 byte units.
8const (
9	Kibibyte Base2Bytes = 1024
10	KiB                 = Kibibyte
11	Mebibyte            = Kibibyte * 1024
12	MiB                 = Mebibyte
13	Gibibyte            = Mebibyte * 1024
14	GiB                 = Gibibyte
15	Tebibyte            = Gibibyte * 1024
16	TiB                 = Tebibyte
17	Pebibyte            = Tebibyte * 1024
18	PiB                 = Pebibyte
19	Exbibyte            = Pebibyte * 1024
20	EiB                 = Exbibyte
21)
22
23var (
24	bytesUnitMap    = MakeUnitMap("iB", "B", 1024)
25	oldBytesUnitMap = MakeUnitMap("B", "B", 1024)
26)
27
28// ParseBase2Bytes supports both iB and B in base-2 multipliers. That is, KB
29// and KiB are both 1024.
30// However "kB", which is the correct SI spelling of 1000 Bytes, is rejected.
31func ParseBase2Bytes(s string) (Base2Bytes, error) {
32	n, err := ParseUnit(s, bytesUnitMap)
33	if err != nil {
34		n, err = ParseUnit(s, oldBytesUnitMap)
35	}
36	return Base2Bytes(n), err
37}
38
39func (b Base2Bytes) String() string {
40	return ToString(int64(b), 1024, "iB", "B")
41}
42
43func (b *Base2Bytes) UnmarshalText(text []byte) error {
44	n, err := ParseBase2Bytes(string(text))
45	*b = n
46	return err
47}
48
49var (
50	metricBytesUnitMap = MakeUnitMap("B", "B", 1000)
51)
52
53// MetricBytes are SI byte units (1000 bytes in a kilobyte).
54type MetricBytes SI
55
56// SI base-10 byte units.
57const (
58	Kilobyte MetricBytes = 1000
59	KB                   = Kilobyte
60	Megabyte             = Kilobyte * 1000
61	MB                   = Megabyte
62	Gigabyte             = Megabyte * 1000
63	GB                   = Gigabyte
64	Terabyte             = Gigabyte * 1000
65	TB                   = Terabyte
66	Petabyte             = Terabyte * 1000
67	PB                   = Petabyte
68	Exabyte              = Petabyte * 1000
69	EB                   = Exabyte
70)
71
72// ParseMetricBytes parses base-10 metric byte units. That is, KB is 1000 bytes.
73func ParseMetricBytes(s string) (MetricBytes, error) {
74	n, err := ParseUnit(s, metricBytesUnitMap)
75	return MetricBytes(n), err
76}
77
78// TODO: represents 1000B as uppercase "KB", while SI standard requires "kB".
79func (m MetricBytes) String() string {
80	return ToString(int64(m), 1000, "B", "B")
81}
82
83// ParseStrictBytes supports both iB and B suffixes for base 2 and metric,
84// respectively. That is, KiB represents 1024 and kB, KB represent 1000.
85func ParseStrictBytes(s string) (int64, error) {
86	n, err := ParseUnit(s, bytesUnitMap)
87	if err != nil {
88		n, err = ParseUnit(s, metricBytesUnitMap)
89	}
90	return int64(n), err
91}
92