1/** 2 * An isomorphic, load-anywhere function to convert a bytes value into a more human-readable format. Choose between [metric or IEC units](https://en.wikipedia.org/wiki/Gigabyte), summarised below. 3 * 4 * Value | Metric 5 * ----- | ------------- 6 * 1000 | kB kilobyte 7 * 1000^2 | MB megabyte 8 * 1000^3 | GB gigabyte 9 * 1000^4 | TB terabyte 10 * 1000^5 | PB petabyte 11 * 1000^6 | EB exabyte 12 * 1000^7 | ZB zettabyte 13 * 1000^8 | YB yottabyte 14 * 15 * Value | IEC 16 * ----- | ------------ 17 * 1024 | KiB kibibyte 18 * 1024^2 | MiB mebibyte 19 * 1024^3 | GiB gibibyte 20 * 1024^4 | TiB tebibyte 21 * 1024^5 | PiB pebibyte 22 * 1024^6 | EiB exbibyte 23 * 1024^7 | ZiB zebibyte 24 * 1024^8 | YiB yobibyte 25 * 26 * Value | Metric (octet) 27 * ----- | ------------- 28 * 1000 | ko kilooctet 29 * 1000^2 | Mo megaoctet 30 * 1000^3 | Go gigaoctet 31 * 1000^4 | To teraoctet 32 * 1000^5 | Po petaoctet 33 * 1000^6 | Eo exaoctet 34 * 1000^7 | Zo zettaoctet 35 * 1000^8 | Yo yottaoctet 36 * 37 * Value | IEC (octet) 38 * ----- | ------------ 39 * 1024 | Kio kilooctet 40 * 1024^2 | Mio mebioctet 41 * 1024^3 | Gio gibioctet 42 * 1024^4 | Tio tebioctet 43 * 1024^5 | Pio pebioctet 44 * 1024^6 | Eio exbioctet 45 * 1024^7 | Zio zebioctet 46 * 1024^8 | Yio yobioctet 47 * 48 * @module byte-size 49 * @example 50 * ```js 51 * const byteSize = require('byte-size') 52 * ``` 53 */ 54 55class ByteSize { 56 constructor (bytes, options) { 57 options = options || {} 58 options.units = options.units || 'metric' 59 options.precision = typeof options.precision === 'undefined' ? 1 : options.precision 60 61 const table = [ 62 { expFrom: 0, expTo: 1, metric: 'B', iec: 'B', metric_octet: 'o', iec_octet: 'o' }, 63 { expFrom: 1, expTo: 2, metric: 'kB', iec: 'KiB', metric_octet: 'ko', iec_octet: 'Kio' }, 64 { expFrom: 2, expTo: 3, metric: 'MB', iec: 'MiB', metric_octet: 'Mo', iec_octet: 'Mio' }, 65 { expFrom: 3, expTo: 4, metric: 'GB', iec: 'GiB', metric_octet: 'Go', iec_octet: 'Gio' }, 66 { expFrom: 4, expTo: 5, metric: 'TB', iec: 'TiB', metric_octet: 'To', iec_octet: 'Tio' }, 67 { expFrom: 5, expTo: 6, metric: 'PB', iec: 'PiB', metric_octet: 'Po', iec_octet: 'Pio' }, 68 { expFrom: 6, expTo: 7, metric: 'EB', iec: 'EiB', metric_octet: 'Eo', iec_octet: 'Eio' }, 69 { expFrom: 7, expTo: 8, metric: 'ZB', iec: 'ZiB', metric_octet: 'Zo', iec_octet: 'Zio' }, 70 { expFrom: 8, expTo: 9, metric: 'YB', iec: 'YiB', metric_octet: 'Yo', iec_octet: 'Yio' } 71 ] 72 73 const base = options.units === 'metric' || options.units === 'metric_octet' ? 1000 : 1024 74 const prefix = bytes < 0 ? '-' : ''; 75 bytes = Math.abs(bytes); 76 77 for (let i = 0; i < table.length; i++) { 78 const lower = Math.pow(base, table[i].expFrom) 79 const upper = Math.pow(base, table[i].expTo) 80 if (bytes >= lower && bytes < upper) { 81 const units = table[i][options.units] 82 if (i === 0) { 83 this.value = prefix + bytes 84 this.unit = units 85 return 86 } else { 87 this.value = prefix + (bytes / lower).toFixed(options.precision) 88 this.unit = units 89 return 90 } 91 } 92 } 93 94 this.value = prefix + bytes 95 this.unit = '' 96 } 97 98 toString () { 99 return `${this.value} ${this.unit}`.trim() 100 } 101} 102 103/** 104 * @param {number} - the bytes value to convert. 105 * @param [options] {object} - optional config. 106 * @param [options.precision=1] {number} - number of decimal places. 107 * @param [options.units=metric] {string} - select `'metric'`, `'iec'`, `'metric_octet'` or `'iec_octet'` units. 108 * @returns {{ value: string, unit: string}} 109 * @alias module:byte-size 110 * @example 111 * ```js 112 * > const byteSize = require('byte-size') 113 * 114 * > byteSize(1580) 115 * { value: '1.6', unit: 'kB' } 116 * 117 * > byteSize(1580, { units: 'iec' }) 118 * { value: '1.5', unit: 'KiB' } 119 * 120 * > byteSize(1580, { units: 'iec', precision: 3 }) 121 * { value: '1.543', unit: 'KiB' } 122 * 123 * > byteSize(1580, { units: 'iec', precision: 0 }) 124 * { value: '2', unit: 'KiB' } 125 * 126 * > byteSize(1580, { units: 'metric_octet' }) 127 * { value: '1.6', unit: 'ko' } 128 * 129 * > byteSize(1580, { units: 'iec_octet' }) 130 * { value: '1.5', unit: 'Kio' } 131 * 132 * > byteSize(1580, { units: 'iec_octet' }).toString() 133 * '1.5 Kio' 134 * 135 * > const { value, unit } = byteSize(1580, { units: 'iec_octet' }) 136 * > `${value} ${unit}` 137 * '1.5 Kio' 138 * ``` 139 */ 140function byteSize (bytes, options) { 141 return new ByteSize(bytes, options) 142} 143 144export default byteSize 145