1 /*
  2  * DigitalSpeedUnit.js - Unit conversions for Digital Storage
  3  *
  4  * Copyright © 2018 JEDLSoft
  5  *
  6  * Licensed under the Apache License, Version 2.0 (the "License");
  7  * you may not use this file except in compliance with the License.
  8  * You may obtain a copy of the License at
  9  *
 10  *     http://www.apache.org/licenses/LICENSE-2.0
 11  *
 12  * Unless required by applicable law or agreed to in writing, software
 13  * distributed under the License is distributed on an "AS IS" BASIS,
 14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 15  *
 16  * See the License for the specific language governing permissions and
 17  * limitations under the License.
 18  */
 19 
 20 /*
 21 !depends
 22 Measurement.js
 23 JSUtils.js
 24 */
 25 
 26 var Measurement = require("./Measurement.js");
 27 var JSUtils = require("./JSUtils.js");
 28 
 29 /**
 30  * @class
 31  * Create a new DigitalSpeed measurement instance. This measures the speed of
 32  * transfer of data.
 33  *
 34  * @constructor
 35  * @extends Measurement
 36  * @param options {{unit:string,amount:number|string|undefined}} Options controlling
 37  * the construction of this instance
 38  */
 39 var DigitalSpeedUnit = function (options) {
 40     this.unit = "byte";
 41     this.amount = 0;
 42 
 43     this.ratios = DigitalSpeedUnit.ratios;
 44     this.aliases = DigitalSpeedUnit.aliases;
 45     this.aliasesLower = DigitalSpeedUnit.aliasesLower;
 46     this.systems = DigitalSpeedUnit.systems;
 47 
 48     this.parent.call(this, options);
 49 };
 50 
 51 DigitalSpeedUnit.prototype = new Measurement();
 52 DigitalSpeedUnit.prototype.parent = Measurement;
 53 DigitalSpeedUnit.prototype.constructor = DigitalSpeedUnit;
 54 
 55 DigitalSpeedUnit.ratios = {
 56     /*                       #    bps               Bps              kbps             kBps             Mbps              MBps              Gbps             GBps               Tbps              TBps              Pbps               PBps               Bph             kBph             MBph             GBph             TBph            PBph   */
 57     "bit-per-second":      [ 1,   1,                0.125,           0.0009765625,    1.220703125e-4,  9.536743164e-7,   1.192092896e-7,   9.313225746e-10, 1.164153218e-10,   9.094947017e-13,  1.136868377e-13,  8.881784197e-16,   1.110223025e-16,   450,            0.45,           4.5e-4,          4.5e-7,          4.5e-10,         4.5e-13         ],
 58     "byte-per-second":     [ 2,   8,                1,               0.0078125,       0.0009765625,    7.629394531e-6,   9.536743164e-7,   7.450580597e-9,  9.313225746e-10,   7.275957614e-12,  9.094947017e-13,  7.105427358e-15,   8.881784197e-16,   3600,           3.6,            3.6e-3,          3.6e-6,          3.6e-9,          3.6e-12         ],
 59     "kilobit-per-second":  [ 3,   1024,             128,             1,               0.125,           0.0009765625,     1.220703125e-4,   9.536743164e-7,  1.192092896e-7,    9.313225746e-10,  1.164153218e-10,  9.094947017e-13,   1.136868377e-13,   4.5e5,          450,            0.45,            4.5e-4,          4.5e-7,          4.5e-10         ],
 60     "kilobyte-per-second": [ 4,   8192,             1024,            8,               1,               0.0078125,        0.0009765625,     7.629394531e-6,  9.536743164e-7,    7.450580597e-9,   9.313225746e-10,  7.275957614e-12,   9.094947017e-13,   3.6e6,          3600,           3.6,             3.6e-3,          3.6e-6,          3.6e-9          ],
 61     "megabit-per-second":  [ 5,   1048576,          131072,          1024,            128,             1,                0.125,            0.0009765625,    1.220703125e-4,    9.536743164e-7,   1.192092896e-7,   9.313225746e-10,   1.164153218e-10,   4.5e8,          4.5e5,          450,             0.45,            4.5e-4,          4.5e-7          ],
 62     "megabyte-per-second": [ 6,   8388608,          1048576,         8192,            1024,            8,                1,                0.0078125,       0.0009765625,      7.629394531e-6,   9.536743164e-7,   7.450580597e-9,    9.313225746e-10,   3.6e9,          3.6e6,          3600,            3.6,             3.6e-3,          3.6e-6          ],
 63     "gigabit-per-second":  [ 7,   1073741824,       134217728,       1048576,         131072,          1024,             128,              1,               0.125,             0.0009765625,     1.220703125e-4,   9.536743164e-7,    1.192092896e-7,    4.5e11,         4.5e8,          4.5e5,           450,             0.45,            4.5e-4          ],
 64     "gigabyte-per-second": [ 8,   8589934592,       1073741824,      8388608,         1048576,         8192,             1024,             8,               1,                 0.0078125,        0.0009765625,     7.629394531e-6,    9.536743164e-7,    3.6e12,         3.6e9,          3.6e6,           3600,            3.6,             3.6e-3          ],
 65     "terabit-per-second":  [ 9,   1.099511628e12,   137438953472,    1073741824,      134217728,       1048576,          131072,           1024,            128,               1,                0.125,            0.0009765625,      1.220703125e-4,    4.5e14,         4.5e11,         4.5e8,           4.5e5,           450,             0.45            ],
 66     "terabyte-per-second": [ 10,  8.796093022e12,   1.099511628e12,  8589934592,      1073741824,      8388608,          1048576,          8192,            1024,              8,                1,                0.0078125,         0.0009765625,      3.6e15,         3.6e12,         3.6e9,           3.6e6,           3600,            3.6             ],
 67     "petabit-per-second":  [ 11,  1.125899907e15,   1.407374884e14,  1.099511628e12,  137438953472,    1073741824,       134217728,        1048576,         131072,            1024,             128,              1,                 0.125,             4.5e17,         4.5e14,         4.5e11,          4.5e8,           4.5e5,           450             ],
 68     "petabyte-per-second": [ 12,  9.007199255e15,   1.125899907e15,  8.796093022e12,  1.099511628e12,  8589934592,       1073741824,       8388608,         1048576,           8192,             1024,             8,                 1,                 3.6e18,         3.6e15,         3.6e12,          3.6e9,           3.6e6,           3600            ],
 69 
 70     "byte-per-hour":       [ 13,  28800,            3600,            28.125,           3.515625,        0.0274658203116, 3.43322753904e-3, 2.68220901492e-5, 3.35276126856e-6, 2.61934474104e-8, 3.27418092612e-9, 2.55795384888e-11, 3.19744231092e-12, 1,              0.0078125,      9.536743164e-7,  9.313225746e-10, 9.094947017e-13, 8.881784197e-16 ],
 71     "kilobyte-per-hour":   [ 14,  29491200,         3686400,         28800,            3600,            28.125,          3.515625,         0.0274658203116,  3.43322753904e-3, 2.68220901492e-5, 3.35276126856e-6, 2.61934474104e-8,  3.27418092612e-9,  1024,           1,              0.0078125,       9.536743164e-7,  9.313225746e-10, 9.094947017e-13 ],
 72     "megabyte-per-hour":   [ 15,  30198988800,      3774873600,      29491200,         3686400,         28800,           3600,             28.125,           3.515625,         0.0274658203116,  3.43322753904e-3, 2.68220901492e-5,  3.35276126856e-6,  1048576,        1024,           1,               0.0078125,       9.536743164e-7,  9.313225746e-10 ],
 73     "gigabyte-per-hour":   [ 16,  30923764531200,   3865470566400,   30198988800,      3774873600,      29491200,        3686400,          28800,            3600,             28.125,           3.515625,         0.0274658203116,   3.43322753904e-3,  1073741824,     1048576,        1024,            1,               0.0078125,       9.536743164e-7  ],
 74     "terabyte-per-hour":   [ 17,  3.16659348792e16, 3.9582418608e16, 30923764531200,   3865470566400,   30198988800,     3774873600,       29491200,         3686400,          28800,            3600,             28.125,            3.515625,          1.099511628e12, 1073741824,     1048576,         1024,            1,               0.0078125       ],
 75     "petabyte-per-hour":   [ 18,  3.2425917318e19,  4.0532396652e18, 3.16659348792e16, 3.9582418608e16, 30923764531200,  3865470566400,    30198988800,      3774873600,       29491200,         3686400,          28800,             3600,              1.125899907e15, 1.099511628e12, 1073741824,      1048576,         1024,            1               ]
 76 };
 77 
 78 /**
 79  * Return a new instance of this type of measurement.
 80  *
 81  * @param {Object} params parameters to the constructor
 82  * @return {Measurement} a measurement subclass instance
 83  */
 84 DigitalSpeedUnit.prototype.newUnit = function(params) {
 85     return new DigitalSpeedUnit(params);
 86 };
 87 
 88 DigitalSpeedUnit.systems = {
 89     "metric": [],
 90     "uscustomary": [],
 91     "imperial": [],
 92     "conversions": {
 93         "metric": {},
 94         "uscustomary": {},
 95         "imperial": {}
 96     }
 97 };
 98 
 99 DigitalSpeedUnit.bitSystem = [
100     "bit-per-second",
101     "kilobit-per-second",
102     "megabit-per-second",
103     "gigabit-per-second",
104     "terabit-per-second",
105     "petabit-per-second"
106 ];
107 DigitalSpeedUnit.byteSystem = [
108     "byte-per-second",
109     "kilobyte-per-second",
110     "megabyte-per-second",
111     "gigabyte-per-second",
112     "terabyte-per-second",
113     "petabyte-per-second"
114 ];
115 
116 /**
117  * Return the type of this measurement. Examples are "mass",
118  * "length", "speed", etc. Measurements can only be converted
119  * to measurements of the same type.<p>
120  *
121  * The type of the units is determined automatically from the
122  * units. For example, the unit "grams" is type "mass". Use the
123  * static call {@link Measurement.getAvailableUnits}
124  * to find out what units this version of ilib supports.
125  *
126  * @override
127  * @return {string} the name of the type of this measurement
128  */
129 DigitalSpeedUnit.prototype.getMeasure = function() {
130     return "digitalSpeed";
131 };
132 
133 /**
134  * Localize the measurement to the commonly used measurement in that locale. For example
135  * If a user's locale is "en-US" and the measurement is given as "60 kmh",
136  * the formatted number should be automatically converted to the most appropriate
137  * measure in the other system, in this case, mph. The formatted result should
138  * appear as "37.3 mph".
139  *
140  * @param {string} locale current locale string
141  * @returns {Measurement} a new instance that is converted to locale
142  */
143 DigitalSpeedUnit.prototype.localize = function(locale) {
144     return new DigitalSpeedUnit({
145         unit: this.unit,
146         amount: this.amount
147     });
148 };
149 
150 /**
151  * Scale the measurement unit to an acceptable level. The scaling
152  * happens so that the integer part of the amount is as small as
153  * possible without being below zero. This will result in the
154  * largest units that can represent this measurement without
155  * fractions. Measurements can only be scaled to other measurements
156  * of the same type.
157  *
158  * @param {string=} measurementsystem system to use (uscustomary|imperial|metric),
159  * or undefined if the system can be inferred from the current measure
160  * @param {Object=} units mapping from the measurement system to the units to use
161  * for this scaling. If this is not defined, this measurement type will use the
162  * set of units that it knows about for the given measurement system
163  * @return {Measurement} a new instance that is scaled to the
164  * right level
165  */
166 DigitalSpeedUnit.prototype.scale = function(measurementsystem, units) {
167     var mSystem, systemName = this.getMeasurementSystem();
168     if (units) {
169         mSystem = units[systemName];
170     } else {
171         if (JSUtils.indexOf(DigitalSpeedUnit.byteSystem, this.unit) > -1) {
172             mSystem = DigitalSpeedUnit.byteSystem;
173         } else {
174             mSystem = DigitalSpeedUnit.bitSystem;
175         }
176     }
177 
178     return this.newUnit(this.scaleUnits(mSystem));
179 };
180 
181 /**
182  * Expand the current measurement such that any fractions of the current unit
183  * are represented in terms of smaller units in the same system instead of fractions
184  * of the current unit. For example, "6.25 feet" may be represented as
185  * "6 feet 4 inches" instead. The return value is an array of measurements which
186  * are progressively smaller until the smallest unit in the system is reached
187  * or until there is a whole number of any unit along the way.
188  *
189  * @param {string=} measurementsystem system to use (uscustomary|imperial|metric),
190  * or undefined if the system can be inferred from the current measure
191  * @param {Object=} units mapping from the measurement system to the units to use
192  * for this scaling. If this is not defined, this measurement type will use the
193  * set of units that it knows about for the given measurement system
194  * @return {Array.<Measurement>} an array of new measurements in order from
195  * the current units to the smallest units in the system which together are the
196  * same measurement as this one
197  */
198 DigitalSpeedUnit.prototype.expand = function(measurementsystem, units) {
199     var mSystem, systemName = this.getMeasurementSystem();
200     if (units) {
201         mSystem = units[systemName];
202     } else {
203         if (this.unit in DigitalSpeedUnit.byteSystem) {
204             mSystem = DigitalSpeedUnit.byteSystem;
205         } else {
206             mSystem = DigitalSpeedUnit.bitSystem;
207         }
208     }
209 
210     return this.list(mSystem, DigitalSpeedUnit.ratios).map(function(item) {
211         return new DigitalSpeedUnit(item);
212     });
213 };
214 
215 DigitalSpeedUnit.aliases = {
216     "bits/s": "bit-per-second",
217     "bit/s": "bit-per-second",
218     "bits/second": "bit-per-second",
219     "bit/second": "bit-per-second",
220     "bps": "bit-per-second",
221     "byte/s": "byte-per-second",
222     "bytes/s": "byte-per-second",
223     "byte/second": "byte-per-second",
224     "bytes/second": "byte-per-second",
225     "Bps": "byte-per-second",
226     "kilobits/s": "kilobit-per-second",
227     "kilobits/second": "kilobit-per-second",
228     "Kilobits/s": "kilobit-per-second",
229     "kilobit/s": "kilobit-per-second",
230     "kilobit/second": "kilobit-per-second",
231     "Kilobit/s": "kilobit-per-second",
232     "kb/s": "kilobit-per-second",
233     "Kb/s": "kilobit-per-second",
234     "kbps": "kilobit-per-second",
235     "Kbps": "kilobit-per-second",
236     "kilobyte/s": "kilobyte-per-second",
237     "kilobyte/second": "kilobyte-per-second",
238     "Kilobyte/s": "kilobyte-per-second",
239     "kilobytes/s": "kilobyte-per-second",
240     "kilobytes/second": "kilobyte-per-second",
241     "Kilobytes/s": "kilobyte-per-second",
242     "kB/s": "kilobyte-per-second",
243     "KB/s": "kilobyte-per-second",
244     "kBps": "kilobyte-per-second",
245     "KBps": "kilobyte-per-second",
246     "megabit/s": "megabit-per-second",
247     "megabits/s": "megabit-per-second",
248     "megabit/second": "megabit-per-second",
249     "megabits/second": "megabit-per-second",
250     "Mb/s": "megabit-per-second",
251     "mb/s": "megabit-per-second",
252     "mbps": "megabit-per-second",
253     "Mbps": "megabit-per-second",
254     "megabyte/s": "megabyte-per-second",
255     "megabytes/s": "megabyte-per-second",
256     "megabyte/second": "megabyte-per-second",
257     "megabytes/second": "megabyte-per-second",
258     "MB/s": "megabyte-per-second",
259     "mB/s": "megabyte-per-second",
260     "mBps": "megabyte-per-second",
261     "MBps": "megabyte-per-second",
262     "gigabit/s": "gigabit-per-second",
263     "gigabits/s": "gigabit-per-second",
264     "gigabit/second": "gigabit-per-second",
265     "gigabits/second": "gigabit-per-second",
266     "Gb/s": "gigabit-per-second",
267     "gb/s": "gigabit-per-second",
268     "gbps": "gigabit-per-second",
269     "Gbps": "gigabit-per-second",
270     "gigabyte/s": "gigabyte-per-second",
271     "gigabytes/s": "gigabyte-per-second",
272     "gigabyte/second": "gigabyte-per-second",
273     "gigabytes/second": "gigabyte-per-second",
274     "GB/s": "gigabyte-per-second",
275     "gB/s": "gigabyte-per-second",
276     "gBps": "gigabyte-per-second",
277     "GBps": "gigabyte-per-second",
278     "terabit/second": "terabit-per-second",
279     "terabits/second": "terabit-per-second",
280     "tb/s": "terabit-per-second",
281     "Tb/s": "terabit-per-second",
282     "tbps": "terabit-per-second",
283     "Tbps": "terabit-per-second",
284     "terabyte/s": "terabyte-per-second",
285     "terabytes/s": "terabyte-per-second",
286     "terabyte/second": "terabyte-per-second",
287     "terabytes/second": "terabyte-per-second",
288     "TB/s": "terabyte-per-second",
289     "tB/s": "terabyte-per-second",
290     "tBps": "terabyte-per-second",
291     "TBps": "terabyte-per-second",
292     "petabit/s": "petabit-per-second",
293     "petabits/s": "petabit-per-second",
294     "petabit/second": "petabit-per-second",
295     "petabits/second": "petabit-per-second",
296     "pb/s": "petabit-per-second",
297     "Pb/s": "petabit-per-second",
298     "pbps": "petabit-per-second",
299     "Pbps": "petabit-per-second",
300     "petabyte/s": "petabyte-per-second",
301     "petabytes/s": "petabyte-per-second",
302     "petabyte/second": "petabyte-per-second",
303     "petabytes/second": "petabyte-per-second",
304     "PB/s": "petabyte-per-second",
305     "pB/s": "petabyte-per-second",
306     "pBps": "petabyte-per-second",
307     "PBps": "petabyte-per-second",
308     "byte/h": "byte-per-hour",
309     "bytes/h": "byte-per-hour",
310     "byte/hour": "byte-per-hour",
311     "bytes/hour": "byte-per-hour",
312     "B/h": "byte-per-hour",
313     "Bph": "byte-per-hour",
314     "kilobyte/h": "kilobyte-per-hour",
315     "kilobytes/h": "kilobyte-per-hour",
316     "kilobyte/hour": "kilobyte-per-hour",
317     "kilobytes/hour": "kilobyte-per-hour",
318     "kB/h": "kilobyte-per-hour",
319     "KB/h": "kilobyte-per-hour",
320     "kBph": "kilobyte-per-hour",
321     "KBph": "kilobyte-per-hour",
322     "megabyte/h": "megabyte-per-hour",
323     "megabytes/h": "megabyte-per-hour",
324     "megabyte/hour": "megabyte-per-hour",
325     "megabytes/hour": "megabyte-per-hour",
326     "MB/h": "megabyte-per-hour",
327     "MBph": "megabyte-per-hour",
328     "gigabyte/h": "gigabyte-per-hour",
329     "gigabytes/h": "gigabyte-per-hour",
330     "gigabyte/hour": "gigabyte-per-hour",
331     "gigabytes/hour": "gigabyte-per-hour",
332     "GB/h": "gigabyte-per-hour",
333     "GBph": "gigabyte-per-hour",
334     "petabyte/h": "petabyte-per-hour",
335     "petabytes/h": "petabyte-per-hour",
336     "petabyte/hour": "petabyte-per-hour",
337     "petabytes/hour": "petabyte-per-hour",
338     "PB/h": "petabyte-per-hour",
339     "PBph": "petabyte-per-hour"
340 };
341 
342 (function() {
343     DigitalSpeedUnit.aliasesLower = {};
344     for (var a in DigitalSpeedUnit.aliases) {
345         DigitalSpeedUnit.aliasesLower[a.toLowerCase()] = DigitalSpeedUnit.aliases[a];
346     }
347 })();
348 
349 /**
350  * Convert a digitalSpeed to another measure.
351  * @static
352  * @param to {string} unit to convert to
353  * @param from {string} unit to convert from
354  * @param digitalSpeed {number} amount to be convert
355  * @returns {number|undefined} the converted amount
356  */
357 DigitalSpeedUnit.convert = function(to, from, digitalSpeed) {
358     from = Measurement.getUnitIdCaseInsensitive(DigitalSpeedUnit, from) || from;
359     to = Measurement.getUnitIdCaseInsensitive(DigitalSpeedUnit, to) || to;
360     var fromRow = DigitalSpeedUnit.ratios[from];
361     var toRow = DigitalSpeedUnit.ratios[to];
362     if (typeof(from) === 'undefined' || typeof(to) === 'undefined') {
363         return undefined;
364     }
365     var result = digitalSpeed * fromRow[toRow[0]];
366     return result;
367 };
368 
369 /**
370  * @private
371  * @static
372  */
373 DigitalSpeedUnit.getMeasures = function () {
374     return Object.keys(DigitalSpeedUnit.ratios);
375 };
376 
377 //register with the factory method
378 Measurement._constructors["digitalSpeed"] = DigitalSpeedUnit;
379 
380 module.exports = DigitalSpeedUnit;