commit inicial
[VSoRC/.git] / node_modules / bytes / index.js
1 /*!
2  * bytes
3  * Copyright(c) 2012-2014 TJ Holowaychuk
4  * Copyright(c) 2015 Jed Watson
5  * MIT Licensed
6  */
7
8 'use strict';
9
10 /**
11  * Module exports.
12  * @public
13  */
14
15 module.exports = bytes;
16 module.exports.format = format;
17 module.exports.parse = parse;
18
19 /**
20  * Module variables.
21  * @private
22  */
23
24 var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
25
26 var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
27
28 var map = {
29   b:  1,
30   kb: 1 << 10,
31   mb: 1 << 20,
32   gb: 1 << 30,
33   tb: Math.pow(1024, 4),
34   pb: Math.pow(1024, 5),
35 };
36
37 var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i;
38
39 /**
40  * Convert the given value in bytes into a string or parse to string to an integer in bytes.
41  *
42  * @param {string|number} value
43  * @param {{
44  *  case: [string],
45  *  decimalPlaces: [number]
46  *  fixedDecimals: [boolean]
47  *  thousandsSeparator: [string]
48  *  unitSeparator: [string]
49  *  }} [options] bytes options.
50  *
51  * @returns {string|number|null}
52  */
53
54 function bytes(value, options) {
55   if (typeof value === 'string') {
56     return parse(value);
57   }
58
59   if (typeof value === 'number') {
60     return format(value, options);
61   }
62
63   return null;
64 }
65
66 /**
67  * Format the given value in bytes into a string.
68  *
69  * If the value is negative, it is kept as such. If it is a float,
70  * it is rounded.
71  *
72  * @param {number} value
73  * @param {object} [options]
74  * @param {number} [options.decimalPlaces=2]
75  * @param {number} [options.fixedDecimals=false]
76  * @param {string} [options.thousandsSeparator=]
77  * @param {string} [options.unit=]
78  * @param {string} [options.unitSeparator=]
79  *
80  * @returns {string|null}
81  * @public
82  */
83
84 function format(value, options) {
85   if (!Number.isFinite(value)) {
86     return null;
87   }
88
89   var mag = Math.abs(value);
90   var thousandsSeparator = (options && options.thousandsSeparator) || '';
91   var unitSeparator = (options && options.unitSeparator) || '';
92   var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
93   var fixedDecimals = Boolean(options && options.fixedDecimals);
94   var unit = (options && options.unit) || '';
95
96   if (!unit || !map[unit.toLowerCase()]) {
97     if (mag >= map.pb) {
98       unit = 'PB';
99     } else if (mag >= map.tb) {
100       unit = 'TB';
101     } else if (mag >= map.gb) {
102       unit = 'GB';
103     } else if (mag >= map.mb) {
104       unit = 'MB';
105     } else if (mag >= map.kb) {
106       unit = 'KB';
107     } else {
108       unit = 'B';
109     }
110   }
111
112   var val = value / map[unit.toLowerCase()];
113   var str = val.toFixed(decimalPlaces);
114
115   if (!fixedDecimals) {
116     str = str.replace(formatDecimalsRegExp, '$1');
117   }
118
119   if (thousandsSeparator) {
120     str = str.replace(formatThousandsRegExp, thousandsSeparator);
121   }
122
123   return str + unitSeparator + unit;
124 }
125
126 /**
127  * Parse the string value into an integer in bytes.
128  *
129  * If no unit is given, it is assumed the value is in bytes.
130  *
131  * @param {number|string} val
132  *
133  * @returns {number|null}
134  * @public
135  */
136
137 function parse(val) {
138   if (typeof val === 'number' && !isNaN(val)) {
139     return val;
140   }
141
142   if (typeof val !== 'string') {
143     return null;
144   }
145
146   // Test if the string passed is valid
147   var results = parseRegExp.exec(val);
148   var floatValue;
149   var unit = 'b';
150
151   if (!results) {
152     // Nothing could be extracted from the given string
153     floatValue = parseInt(val, 10);
154     unit = 'b'
155   } else {
156     // Retrieve the value and the unit
157     floatValue = parseFloat(results[1]);
158     unit = results[4].toLowerCase();
159   }
160
161   return Math.floor(map[unit] * floatValue);
162 }