3 * Copyright(c) 2012-2014 TJ Holowaychuk
4 * Copyright(c) 2015 Jed Watson
15 module.exports = bytes;
16 module.exports.format = format;
17 module.exports.parse = parse;
24 var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g;
26 var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/;
33 tb: ((1 << 30) * 1024)
36 var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i;
39 * Convert the given value in bytes into a string or parse to string to an integer in bytes.
41 * @param {string|number} value
44 * decimalPlaces: [number]
45 * fixedDecimals: [boolean]
46 * thousandsSeparator: [string]
47 * unitSeparator: [string]
48 * }} [options] bytes options.
50 * @returns {string|number|null}
53 function bytes(value, options) {
54 if (typeof value === 'string') {
58 if (typeof value === 'number') {
59 return format(value, options);
66 * Format the given value in bytes into a string.
68 * If the value is negative, it is kept as such. If it is a float,
71 * @param {number} value
72 * @param {object} [options]
73 * @param {number} [options.decimalPlaces=2]
74 * @param {number} [options.fixedDecimals=false]
75 * @param {string} [options.thousandsSeparator=]
76 * @param {string} [options.unit=]
77 * @param {string} [options.unitSeparator=]
79 * @returns {string|null}
83 function format(value, options) {
84 if (!Number.isFinite(value)) {
88 var mag = Math.abs(value);
89 var thousandsSeparator = (options && options.thousandsSeparator) || '';
90 var unitSeparator = (options && options.unitSeparator) || '';
91 var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
92 var fixedDecimals = Boolean(options && options.fixedDecimals);
93 var unit = (options && options.unit) || '';
95 if (!unit || !map[unit.toLowerCase()]) {
98 } else if (mag >= map.gb) {
100 } else if (mag >= map.mb) {
102 } else if (mag >= map.kb) {
109 var val = value / map[unit.toLowerCase()];
110 var str = val.toFixed(decimalPlaces);
112 if (!fixedDecimals) {
113 str = str.replace(formatDecimalsRegExp, '$1');
116 if (thousandsSeparator) {
117 str = str.replace(formatThousandsRegExp, thousandsSeparator);
120 return str + unitSeparator + unit;
124 * Parse the string value into an integer in bytes.
126 * If no unit is given, it is assumed the value is in bytes.
128 * @param {number|string} val
130 * @returns {number|null}
134 function parse(val) {
135 if (typeof val === 'number' && !isNaN(val)) {
139 if (typeof val !== 'string') {
143 // Test if the string passed is valid
144 var results = parseRegExp.exec(val);
149 // Nothing could be extracted from the given string
150 floatValue = parseInt(val, 10);
153 // Retrieve the value and the unit
154 floatValue = parseFloat(results[1]);
155 unit = results[4].toLowerCase();
158 return Math.floor(map[unit] * floatValue);