1 /* 2 * DigitalStorageUnit.js - Unit conversions for Digital Storage 3 * 4 * Copyright © 2014-2015, 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 DigitalStorage measurement instance. 32 * 33 * @constructor 34 * @extends Measurement 35 * @param options {{unit:string,amount:number|string|undefined}} Options controlling 36 * the construction of this instance 37 */ 38 var DigitalStorageUnit = function (options) { 39 this.unit = "byte"; 40 this.amount = 0; 41 42 this.ratios = DigitalStorageUnit.ratios; 43 this.aliases = DigitalStorageUnit.aliases; 44 this.aliasesLower = DigitalStorageUnit.aliasesLower; 45 this.systems = DigitalStorageUnit.systems; 46 47 this.parent.call(this, options); 48 }; 49 50 DigitalStorageUnit.prototype = new Measurement(); 51 DigitalStorageUnit.prototype.parent = Measurement; 52 DigitalStorageUnit.prototype.constructor = DigitalStorageUnit; 53 54 DigitalStorageUnit.ratios = { 55 /* # bit byte kb kB mb mB gb gB tb tB pb pB */ 56 "bit": [ 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 ], 57 "byte": [ 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 ], 58 "kilobit": [ 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 ], 59 "kilobyte": [ 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 ], 60 "megabit": [ 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 ], 61 "megabyte": [ 6, 8388608, 1048576, 8192, 1024, 8, 1, 0.0078125, 0.0009765625, 7.629394531e-6, 9.536743164e-7, 7.450580597e-9, 9.313225746e-10 ], 62 "gigabit": [ 7, 1073741824, 134217728, 1048576, 131072, 1024, 128, 1, 0.125, 0.0009765625, 1.220703125e-4, 9.536743164e-7, 1.192092896e-7 ], 63 "gigabyte": [ 8, 8589934592, 1073741824, 8388608, 1048576, 8192, 1024, 8, 1, 0.0078125, 0.0009765625, 7.629394531e-6, 9.536743164e-7 ], 64 "terabit": [ 9, 1.099511628e12, 137438953472, 1073741824, 134217728, 1048576, 131072, 1024, 128, 1, 0.125, 0.0009765625, 1.220703125e-4 ], 65 "terabyte": [ 10, 8.796093022e12, 1.099511628e12, 8589934592, 1073741824, 8388608, 1048576, 8192, 1024, 8, 1, 0.0078125, 0.0009765625 ], 66 "petabit": [ 11, 1.125899907e15, 1.407374884e14, 1.099511628e12, 137438953472, 1073741824, 134217728, 1048576, 131072, 1024, 128, 1, 0.125 ], 67 "petabyte": [ 12, 9.007199255e15, 1.125899907e15, 8.796093022e12, 1.099511628e12, 8589934592, 1073741824, 8388608, 1048576, 8192, 1024, 8, 1 ] 68 }; 69 70 /** 71 * Return a new instance of this type of measurement. 72 * 73 * @param {Object} params parameters to the constructor 74 * @return {Measurement} a measurement subclass instance 75 */ 76 DigitalStorageUnit.prototype.newUnit = function(params) { 77 return new DigitalStorageUnit(params); 78 }; 79 80 DigitalStorageUnit.systems = { 81 "metric": [], 82 "uscustomary": [], 83 "imperial": [], 84 "conversions": { 85 "metric": {}, 86 "uscustomary": {}, 87 "imperial": {} 88 } 89 }; 90 91 DigitalStorageUnit.bitSystem = [ 92 "bit", 93 "kilobit", 94 "megabit", 95 "gigabit", 96 "terabit", 97 "petabit" 98 ]; 99 DigitalStorageUnit.byteSystem = [ 100 "byte", 101 "kilobyte", 102 "megabyte", 103 "gigabyte", 104 "terabyte", 105 "petabyte" 106 ]; 107 108 /** 109 * Return the type of this measurement. Examples are "mass", 110 * "length", "speed", etc. Measurements can only be converted 111 * to measurements of the same type.<p> 112 * 113 * The type of the units is determined automatically from the 114 * units. For example, the unit "grams" is type "mass". Use the 115 * static call {@link Measurement.getAvailableUnits} 116 * to find out what units this version of ilib supports. 117 * 118 * @return {string} the name of the type of this measurement 119 */ 120 DigitalStorageUnit.prototype.getMeasure = function() { 121 return "digitalStorage"; 122 }; 123 124 /** 125 * Localize the measurement to the commonly used measurement in that locale. For example 126 * If a user's locale is "en-US" and the measurement is given as "60 kmh", 127 * the formatted number should be automatically converted to the most appropriate 128 * measure in the other system, in this case, mph. The formatted result should 129 * appear as "37.3 mph". 130 * 131 * @param {string} locale current locale string 132 * @returns {Measurement} a new instance that is converted to locale 133 */ 134 DigitalStorageUnit.prototype.localize = function(locale) { 135 return new DigitalStorageUnit({ 136 unit: this.unit, 137 amount: this.amount 138 }); 139 }; 140 141 /** 142 * Scale the measurement unit to an acceptable level. The scaling 143 * happens so that the integer part of the amount is as small as 144 * possible without being below zero. This will result in the 145 * largest units that can represent this measurement without 146 * fractions. Measurements can only be scaled to other measurements 147 * of the same type. 148 * 149 * @param {string=} measurementsystem system to use (uscustomary|imperial|metric), 150 * or undefined if the system can be inferred from the current measure 151 * @param {Object=} units mapping from the measurement system to the units to use 152 * for this scaling. If this is not defined, this measurement type will use the 153 * set of units that it knows about for the given measurement system 154 * @return {Measurement} a new instance that is scaled to the 155 * right level 156 */ 157 DigitalStorageUnit.prototype.scale = function(measurementsystem, units) { 158 var mSystem, systemName = this.getMeasurementSystem(); 159 if (units) { 160 mSystem = units[systemName]; 161 } else { 162 if (JSUtils.indexOf(DigitalStorageUnit.byteSystem, this.unit) > -1) { 163 mSystem = DigitalStorageUnit.byteSystem; 164 } else { 165 mSystem = DigitalStorageUnit.bitSystem; 166 } 167 } 168 169 return this.newUnit(this.scaleUnits(mSystem)); 170 }; 171 172 /** 173 * Expand the current measurement such that any fractions of the current unit 174 * are represented in terms of smaller units in the same system instead of fractions 175 * of the current unit. For example, "6.25 feet" may be represented as 176 * "6 feet 4 inches" instead. The return value is an array of measurements which 177 * are progressively smaller until the smallest unit in the system is reached 178 * or until there is a whole number of any unit along the way. 179 * 180 * @param {string=} measurementsystem system to use (uscustomary|imperial|metric), 181 * or undefined if the system can be inferred from the current measure 182 * @param {Object=} units mapping from the measurement system to the units to use 183 * for this scaling. If this is not defined, this measurement type will use the 184 * set of units that it knows about for the given measurement system 185 * @return {Array.<Measurement>} an array of new measurements in order from 186 * the current units to the smallest units in the system which together are the 187 * same measurement as this one 188 */ 189 DigitalStorageUnit.prototype.expand = function(measurementsystem, units) { 190 var mSystem, systemName = this.getMeasurementSystem(); 191 if (units) { 192 mSystem = units[systemName]; 193 } else { 194 if (this.unit in DigitalStorageUnit.byteSystem) { 195 mSystem = DigitalStorageUnit.byteSystem; 196 } else { 197 mSystem = DigitalStorageUnit.bitSystem; 198 } 199 } 200 201 return this.list(mSystem, DigitalStorageUnit.ratios).map(function(item) { 202 return new DigitalStorageUnit(item); 203 }); 204 }; 205 206 207 DigitalStorageUnit.aliases = { 208 "bits": "bit", 209 "bit": "bit", 210 "Bits": "bit", 211 "Bit": "bit", 212 "byte": "byte", 213 "bytes": "byte", 214 "Byte": "byte", 215 "Bytes": "byte", 216 "kilobits": "kilobit", 217 "Kilobits": "kilobit", 218 "KiloBits": "kilobit", 219 "kiloBits": "kilobit", 220 "kilobit": "kilobit", 221 "Kilobit": "kilobit", 222 "kiloBit": "kilobit", 223 "KiloBit": "kilobit", 224 "kb": "kilobit", 225 "Kb": "kilobit", 226 "kilobyte": "kilobyte", 227 "Kilobyte": "kilobyte", 228 "kiloByte": "kilobyte", 229 "KiloByte": "kilobyte", 230 "kilobytes": "kilobyte", 231 "Kilobytes": "kilobyte", 232 "kiloBytes": "kilobyte", 233 "KiloBytes": "kilobyte", 234 "kB": "kilobyte", 235 "KB": "kilobyte", 236 "megabit": "megabit", 237 "Megabit": "megabit", 238 "megaBit": "megabit", 239 "MegaBit": "megabit", 240 "megabits": "megabit", 241 "Megabits": "megabit", 242 "megaBits": "megabit", 243 "MegaBits": "megabit", 244 "Mb": "megabit", 245 "mb": "megabit", 246 "megabyte": "megabyte", 247 "Megabyte": "megabyte", 248 "megaByte": "megabyte", 249 "MegaByte": "megabyte", 250 "megabytes": "megabyte", 251 "Megabytes": "megabyte", 252 "megaBytes": "megabyte", 253 "MegaBytes": "megabyte", 254 "MB": "megabyte", 255 "mB": "megabyte", 256 "gigabit": "gigabit", 257 "Gigabit": "gigabit", 258 "gigaBit": "gigabit", 259 "GigaBit": "gigabit", 260 "gigabits": "gigabit", 261 "Gigabits": "gigabit", 262 "gigaBits": "gigabyte", 263 "GigaBits": "gigabit", 264 "Gb": "gigabit", 265 "gb": "gigabit", 266 "gigabyte": "gigabyte", 267 "Gigabyte": "gigabyte", 268 "gigaByte": "gigabyte", 269 "GigaByte": "gigabyte", 270 "gigabytes": "gigabyte", 271 "Gigabytes": "gigabyte", 272 "gigaBytes": "gigabyte", 273 "GigaBytes": "gigabyte", 274 "GB": "gigabyte", 275 "gB": "gigabyte", 276 "terabit": "terabit", 277 "Terabit": "terabit", 278 "teraBit": "terabit", 279 "TeraBit": "terabit", 280 "terabits": "terabit", 281 "Terabits": "terabit", 282 "teraBits": "terabit", 283 "TeraBits": "terabit", 284 "tb": "terabit", 285 "Tb": "terabit", 286 "terabyte": "terabyte", 287 "Terabyte": "terabyte", 288 "teraByte": "terabyte", 289 "TeraByte": "terabyte", 290 "terabytes": "terabyte", 291 "Terabytes": "terabyte", 292 "teraBytes": "terabyte", 293 "TeraBytes": "terabyte", 294 "TB": "terabyte", 295 "tB": "terabyte", 296 "petabit": "petabit", 297 "Petabit": "petabit", 298 "petaBit": "petabit", 299 "PetaBit": "petabit", 300 "petabits": "petabit", 301 "Petabits": "petabit", 302 "petaBits": "petabit", 303 "PetaBits": "petabit", 304 "pb": "petabit", 305 "Pb": "petabit", 306 "petabyte": "petabyte", 307 "Petabyte": "petabyte", 308 "petaByte": "petabyte", 309 "PetaByte": "petabyte", 310 "petabytes": "petabyte", 311 "Petabytes": "petabyte", 312 "petaBytes": "petabyte", 313 "PetaBytes": "petabyte", 314 "PB": "petabyte", 315 "pB": "petabyte" 316 }; 317 318 (function() { 319 DigitalStorageUnit.aliasesLower = {}; 320 for (var a in DigitalStorageUnit.aliases) { 321 DigitalStorageUnit.aliasesLower[a.toLowerCase()] = DigitalStorageUnit.aliases[a]; 322 } 323 })(); 324 325 /** 326 * Convert a digitalStorage to another measure. 327 * @static 328 * @param to {string} unit to convert to 329 * @param from {string} unit to convert from 330 * @param digitalStorage {number} amount to be convert 331 * @returns {number|undefined} the converted amount 332 */ 333 DigitalStorageUnit.convert = function(to, from, digitalStorage) { 334 from = Measurement.getUnitIdCaseInsensitive(DigitalStorageUnit, from) || from; 335 to = Measurement.getUnitIdCaseInsensitive(DigitalStorageUnit, to) || to; 336 var fromRow = DigitalStorageUnit.ratios[from]; 337 var toRow = DigitalStorageUnit.ratios[to]; 338 if (typeof(from) === 'undefined' || typeof(to) === 'undefined') { 339 return undefined; 340 } 341 var result = digitalStorage * fromRow[toRow[0]]; 342 return result; 343 }; 344 345 /** 346 * @private 347 * @static 348 */ 349 DigitalStorageUnit.getMeasures = function () { 350 return Object.keys(DigitalStorageUnit.ratios); 351 }; 352 353 //register with the factory method 354 Measurement._constructors["digitalStorage"] = DigitalStorageUnit; 355 356 module.exports = DigitalStorageUnit; 357