Spaces:
Running
Running
/*! | |
* bytes | |
* Copyright(c) 2012-2014 TJ Holowaychuk | |
* Copyright(c) 2015 Jed Watson | |
* MIT Licensed | |
*/ | |
; | |
/** | |
* Module exports. | |
* @public | |
*/ | |
module.exports = bytes; | |
module.exports.format = format; | |
module.exports.parse = parse; | |
/** | |
* Module variables. | |
* @private | |
*/ | |
var formatThousandsRegExp = /\B(?=(\d{3})+(?!\d))/g; | |
var formatDecimalsRegExp = /(?:\.0*|(\.[^0]+)0+)$/; | |
var map = { | |
b: 1, | |
kb: 1 << 10, | |
mb: 1 << 20, | |
gb: 1 << 30, | |
tb: Math.pow(1024, 4), | |
pb: Math.pow(1024, 5), | |
}; | |
var parseRegExp = /^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb|pb)$/i; | |
/** | |
* Convert the given value in bytes into a string or parse to string to an integer in bytes. | |
* | |
* @param {string|number} value | |
* @param {{ | |
* case: [string], | |
* decimalPlaces: [number] | |
* fixedDecimals: [boolean] | |
* thousandsSeparator: [string] | |
* unitSeparator: [string] | |
* }} [options] bytes options. | |
* | |
* @returns {string|number|null} | |
*/ | |
function bytes(value, options) { | |
if (typeof value === 'string') { | |
return parse(value); | |
} | |
if (typeof value === 'number') { | |
return format(value, options); | |
} | |
return null; | |
} | |
/** | |
* Format the given value in bytes into a string. | |
* | |
* If the value is negative, it is kept as such. If it is a float, | |
* it is rounded. | |
* | |
* @param {number} value | |
* @param {object} [options] | |
* @param {number} [options.decimalPlaces=2] | |
* @param {number} [options.fixedDecimals=false] | |
* @param {string} [options.thousandsSeparator=] | |
* @param {string} [options.unit=] | |
* @param {string} [options.unitSeparator=] | |
* | |
* @returns {string|null} | |
* @public | |
*/ | |
function format(value, options) { | |
if (!Number.isFinite(value)) { | |
return null; | |
} | |
var mag = Math.abs(value); | |
var thousandsSeparator = (options && options.thousandsSeparator) || ''; | |
var unitSeparator = (options && options.unitSeparator) || ''; | |
var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2; | |
var fixedDecimals = Boolean(options && options.fixedDecimals); | |
var unit = (options && options.unit) || ''; | |
if (!unit || !map[unit.toLowerCase()]) { | |
if (mag >= map.pb) { | |
unit = 'PB'; | |
} else if (mag >= map.tb) { | |
unit = 'TB'; | |
} else if (mag >= map.gb) { | |
unit = 'GB'; | |
} else if (mag >= map.mb) { | |
unit = 'MB'; | |
} else if (mag >= map.kb) { | |
unit = 'KB'; | |
} else { | |
unit = 'B'; | |
} | |
} | |
var val = value / map[unit.toLowerCase()]; | |
var str = val.toFixed(decimalPlaces); | |
if (!fixedDecimals) { | |
str = str.replace(formatDecimalsRegExp, '$1'); | |
} | |
if (thousandsSeparator) { | |
str = str.split('.').map(function (s, i) { | |
return i === 0 | |
? s.replace(formatThousandsRegExp, thousandsSeparator) | |
: s | |
}).join('.'); | |
} | |
return str + unitSeparator + unit; | |
} | |
/** | |
* Parse the string value into an integer in bytes. | |
* | |
* If no unit is given, it is assumed the value is in bytes. | |
* | |
* @param {number|string} val | |
* | |
* @returns {number|null} | |
* @public | |
*/ | |
function parse(val) { | |
if (typeof val === 'number' && !isNaN(val)) { | |
return val; | |
} | |
if (typeof val !== 'string') { | |
return null; | |
} | |
// Test if the string passed is valid | |
var results = parseRegExp.exec(val); | |
var floatValue; | |
var unit = 'b'; | |
if (!results) { | |
// Nothing could be extracted from the given string | |
floatValue = parseInt(val, 10); | |
unit = 'b' | |
} else { | |
// Retrieve the value and the unit | |
floatValue = parseFloat(results[1]); | |
unit = results[4].toLowerCase(); | |
} | |
if (isNaN(floatValue)) { | |
return null; | |
} | |
return Math.floor(map[unit] * floatValue); | |
} | |