1package cunits
2
3import (
4	"fmt"
5	"regexp"
6	"strconv"
7	"strings"
8)
9
10const parseRegex = "^([0-9,]+(\\.[0-9]+)?) ?(([KMGTPEZY]i?)?(B|bit))$"
11
12var sizeMatch = regexp.MustCompile(parseRegex)
13
14// Parse parses un string representation of a number with a suffix
15func Parse(sizeSuffix string) (size Bits, err error) {
16	// Does it match ?
17	match := sizeMatch.FindSubmatch([]byte(sizeSuffix))
18	if match == nil {
19		err = fmt.Errorf("string does not match the parsing regex: %s", parseRegex)
20		return
21	}
22	if len(match) < 4 {
23		err = fmt.Errorf("regex matching did not return enough groups")
24		return
25	}
26	// Extract number
27	num, err := strconv.ParseFloat(strings.Replace(string(match[1]), ",", "", -1), 64)
28	if err != nil {
29		err = fmt.Errorf("extracted number '%s' can't be parsed as float64: %v", string(match[1]), err)
30		return
31	}
32	// Findout the unit
33	switch string(match[3]) {
34	case "bit":
35		size = Bits(num)
36	case "B":
37		size = ImportInByte(num)
38	// Decimal prefix of bits
39	case "Kbit":
40		size = ImportInKbit(num)
41	case "Mbit":
42		size = ImportInMbit(num)
43	case "Gbit":
44		size = ImportInGbit(num)
45	case "Tbit":
46		size = ImportInTbit(num)
47	case "Pbit":
48		size = ImportInPbit(num)
49	case "Ebit":
50		size = ImportInEbit(num)
51	case "Zbit":
52		size = ImportInZbit(num)
53	case "Ybit":
54		size = ImportInYbit(num)
55	// Binary prefix of bits
56	case "Kibit":
57		size = ImportInKibit(num)
58	case "Mibit":
59		size = ImportInMibit(num)
60	case "Gibit":
61		size = ImportInGibit(num)
62	case "Tibit":
63		size = ImportInTibit(num)
64	case "Pibit":
65		size = ImportInPibit(num)
66	case "Eibit":
67		size = ImportInEibit(num)
68	case "Zibit":
69		size = ImportInZibit(num)
70	case "Yibit":
71		size = ImportInYibit(num)
72	// Decimal prefix of bytes
73	case "KB":
74		size = ImportInKB(num)
75	case "MB":
76		size = ImportInMB(num)
77	case "GB":
78		size = ImportInGB(num)
79	case "TB":
80		size = ImportInTB(num)
81	case "PB":
82		size = ImportInPB(num)
83	case "EB":
84		size = ImportInEB(num)
85	case "ZB":
86		size = ImportInZB(num)
87	case "YB":
88		size = ImportInYB(num)
89	// Binary prefix of bytes
90	case "KiB":
91		size = ImportInKiB(num)
92	case "MiB":
93		size = ImportInMiB(num)
94	case "GiB":
95		size = ImportInGiB(num)
96	case "TiB":
97		size = ImportInTiB(num)
98	case "PiB":
99		size = ImportInPiB(num)
100	case "EiB":
101		size = ImportInEiB(num)
102	case "ZiB":
103		size = ImportInZiB(num)
104	case "YiB":
105		size = ImportInYiB(num)
106	// or not
107	default:
108		err = fmt.Errorf("extracted unit '%s' is unknown", string(match[3]))
109	}
110	return
111}
112
113// ImportInByte imports a number in byte
114func ImportInByte(sizeInByte float64) Bits {
115	return Bits(sizeInByte * Byte)
116}
117
118/*
119	Decimal prefix of bits
120*/
121
122// ImportInKbit imports a number in kilobit
123func ImportInKbit(sizeInKbit float64) Bits {
124	return Bits(sizeInKbit * Kbit)
125}
126
127// ImportInMbit imports a number in megabit
128func ImportInMbit(sizeInMbit float64) Bits {
129	return Bits(sizeInMbit * Mbit)
130}
131
132// ImportInGbit imports a number in gigabit
133func ImportInGbit(sizeInGbit float64) Bits {
134	return Bits(sizeInGbit * Gbit)
135}
136
137// ImportInTbit imports a number in terabit
138func ImportInTbit(sizeInTbit float64) Bits {
139	return Bits(sizeInTbit * Tbit)
140}
141
142// ImportInPbit imports a number in petabit
143func ImportInPbit(sizeInPbit float64) Bits {
144	return Bits(sizeInPbit * Pbit)
145}
146
147// ImportInEbit imports a number in exabit
148func ImportInEbit(sizeInEbit float64) Bits {
149	return Bits(sizeInEbit * Ebit)
150}
151
152// ImportInZbit imports a number in zettabit (sizeInZbit better < 1)
153func ImportInZbit(sizeInZbit float64) Bits {
154	return Bits(sizeInZbit * Zbit)
155}
156
157// ImportInYbit imports a number in yottabit (sizeInYbit better < 1)
158func ImportInYbit(sizeInYbit float64) Bits {
159	return Bits(sizeInYbit * Ybit)
160}
161
162/*
163	Binary prefix of bits
164*/
165
166// ImportInKibit imports a number in kibibit
167func ImportInKibit(sizeInKibit float64) Bits {
168	return Bits(sizeInKibit * Kibit)
169}
170
171// ImportInMibit imports a number in mebibit
172func ImportInMibit(sizeInMibit float64) Bits {
173	return Bits(sizeInMibit * Mibit)
174}
175
176// ImportInGibit imports a number in gibibit
177func ImportInGibit(sizeInGibit float64) Bits {
178	return Bits(sizeInGibit * Gibit)
179}
180
181// ImportInTibit imports a number in tebibit
182func ImportInTibit(sizeInTibit float64) Bits {
183	return Bits(sizeInTibit * Tibit)
184}
185
186// ImportInPibit imports a number in pebibit
187func ImportInPibit(sizeInPibit float64) Bits {
188	return Bits(sizeInPibit * Pibit)
189}
190
191// ImportInEibit imports a number in exbibit
192func ImportInEibit(sizeInEibit float64) Bits {
193	return Bits(sizeInEibit * Eibit)
194}
195
196// ImportInZibit imports a number in zebibit (sizeInZibit better < 1)
197func ImportInZibit(sizeInZibit float64) Bits {
198	return Bits(sizeInZibit * Zibit)
199}
200
201// ImportInYibit imports a number in yobibit (sizeInYibit better < 1)
202func ImportInYibit(sizeInYibit float64) Bits {
203	return Bits(sizeInYibit * Yibit)
204}
205
206/*
207	Decimal prefix of bytes
208*/
209
210// ImportInKB imports a number in kilobyte
211func ImportInKB(sizeInKB float64) Bits {
212	return Bits(sizeInKB * KB)
213}
214
215// ImportInMB imports a number in megabyte
216func ImportInMB(sizeInMB float64) Bits {
217	return Bits(sizeInMB * MB)
218}
219
220// ImportInGB imports a number in gigabyte
221func ImportInGB(sizeInGB float64) Bits {
222	return Bits(sizeInGB * GB)
223}
224
225// ImportInTB imports a number in terabyte
226func ImportInTB(sizeInTB float64) Bits {
227	return Bits(sizeInTB * TB)
228}
229
230// ImportInPB imports a number in petabyte
231func ImportInPB(sizeInPB float64) Bits {
232	return Bits(sizeInPB * PB)
233}
234
235// ImportInEB imports a number in exabyte
236func ImportInEB(sizeInEB float64) Bits {
237	return Bits(sizeInEB * EB)
238}
239
240// ImportInZB imports a number in zettabyte (sizeInZB better < 1)
241func ImportInZB(sizeInZB float64) Bits {
242	return Bits(sizeInZB * ZB)
243}
244
245// ImportInYB imports a number in yottabyte (sizeInYB better < 1)
246func ImportInYB(sizeInYB float64) Bits {
247	return Bits(sizeInYB * YB)
248}
249
250/*
251	Binary prefix of bytes
252*/
253
254// ImportInKiB imports a number in kilobyte
255func ImportInKiB(sizeInKiB float64) Bits {
256	return Bits(sizeInKiB * KiB)
257}
258
259// ImportInMiB imports a number in megabyte
260func ImportInMiB(sizeInMiB float64) Bits {
261	return Bits(sizeInMiB * MiB)
262}
263
264// ImportInGiB imports a number in gigabyte
265func ImportInGiB(sizeInGiB float64) Bits {
266	return Bits(sizeInGiB * GiB)
267}
268
269// ImportInTiB imports a number in terabyte
270func ImportInTiB(sizeInTiB float64) Bits {
271	return Bits(sizeInTiB * TiB)
272}
273
274// ImportInPiB imports a number in petabyte
275func ImportInPiB(sizeInPiB float64) Bits {
276	return Bits(sizeInPiB * PiB)
277}
278
279// ImportInEiB imports a number in exabyte (sizeInEiB better < 1)
280func ImportInEiB(sizeInEiB float64) Bits {
281	return Bits(sizeInEiB * EiB)
282}
283
284// ImportInZiB imports a number in zettabyte (sizeInZiB better < 1)
285func ImportInZiB(sizeInZiB float64) Bits {
286	return Bits(sizeInZiB * ZiB)
287}
288
289// ImportInYiB imports a number in yottabyte (sizeInYiB better < 1)
290func ImportInYiB(sizeInYiB float64) Bits {
291	return Bits(sizeInYiB * YiB)
292}
293