You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

159 lines
3.3 KiB

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