twitst4tz

twitter statistics web application
Log | Files | Refs | README | LICENSE

index.js (3469B)


      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 }