Initial commit
[yaffs-website] / node_modules / bytes / index.js
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 map = {
25   b:  1,
26   kb: 1 << 10,
27   mb: 1 << 20,
28   gb: 1 << 30,
29   tb: ((1 << 30) * 1024)
30 };
31
32 /**
33  *Convert the given value in bytes into a string or parse to string to an integer in bytes.
34  *
35  * @param {string|number} value
36  * @param {{
37  *  case: [string],
38  *  decimalPlaces: [number]
39  *  fixedDecimals: [boolean]
40  *  thousandsSeparator: [string]
41  *  }} [options] bytes options.
42  *
43  * @returns {string|number|null}
44  */
45
46 function bytes(value, options) {
47   if (typeof value === 'string') {
48     return parse(value);
49   }
50
51   if (typeof value === 'number') {
52     return format(value, options);
53   }
54
55   return null;
56 }
57
58 /**
59  * Format the given value in bytes into a string.
60  *
61  * If the value is negative, it is kept as such. If it is a float,
62  * it is rounded.
63  *
64  * @param {number} value
65  * @param {object} [options]
66  * @param {number} [options.decimalPlaces=2]
67  * @param {number} [options.fixedDecimals=false]
68  * @param {string} [options.thousandsSeparator=]
69  * @public
70  */
71
72 function format(value, options) {
73   if (typeof value !== 'number') {
74     return null;
75   }
76
77   var mag = Math.abs(value);
78   var thousandsSeparator = (options && options.thousandsSeparator) || '';
79   var decimalPlaces = (options && options.decimalPlaces !== undefined) ? options.decimalPlaces : 2;
80   var fixedDecimals = Boolean(options && options.fixedDecimals);
81   var unit = 'B';
82
83   if (mag >= map.tb) {
84     unit = 'TB';
85   } else if (mag >= map.gb) {
86     unit = 'GB';
87   } else if (mag >= map.mb) {
88     unit = 'MB';
89   } else if (mag >= map.kb) {
90     unit = 'kB';
91   }
92
93   var val = value / map[unit.toLowerCase()];
94   var str = val.toFixed(decimalPlaces);
95
96   if (!fixedDecimals) {
97     str = str.replace(/(?:\.0*|(\.[^0]+)0+)$/, '$1');
98   }
99
100   if (thousandsSeparator) {
101     str = str.replace(/\B(?=(\d{3})+(?!\d))/g, thousandsSeparator);
102   }
103
104   return str + unit;
105 }
106
107 /**
108  * Parse the string value into an integer in bytes.
109  *
110  * If no unit is given, it is assumed the value is in bytes.
111  *
112  * @param {number|string} val
113  * @public
114  */
115
116 function parse(val) {
117   if (typeof val === 'number' && !isNaN(val)) {
118     return val;
119   }
120
121   if (typeof val !== 'string') {
122     return null;
123   }
124
125   // Test if the string passed is valid
126   var results = val.match(/^((-|\+)?(\d+(?:\.\d+)?)) *(kb|mb|gb|tb)$/i);
127   var floatValue;
128   var unit = 'b';
129
130   if (!results) {
131     // Nothing could be extracted from the given string
132     floatValue = parseInt(val);
133     unit = 'b'
134   } else {
135     // Retrieve the value and the unit
136     floatValue = parseFloat(results[1]);
137     unit = results[4].toLowerCase();
138   }
139
140   return map[unit] * floatValue;
141 }