├── .editorconfig ├── .eslintignore ├── .eslintrc ├── .github ├── FUNDING.yml └── workflows │ └── node.yml ├── .gitignore ├── .npmignore ├── .travis.yml ├── README.md ├── dist ├── enum-3.0.4.js └── enum-3.0.4.min.js ├── index.js ├── lib ├── enum.js ├── enumItem.js ├── indexOf.js └── isType.js ├── licence ├── package.json └── test ├── buffer.js ├── enumTest.js ├── package.json └── test.html /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig is awesome: http://EditorConfig.org 2 | root = true 3 | 4 | [*.{js,jsx,json}] 5 | end_of_line = lf 6 | insert_final_newline = true 7 | charset = utf-8 8 | indent_style = space 9 | indent_size = 2 10 | trim_trailing_whitespace = true 11 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | /build 2 | /node_modules 3 | /cjs 4 | /dist 5 | /test -------------------------------------------------------------------------------- /.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "standard", 4 | "plugin:require-path-exists/recommended" 5 | ], 6 | "plugins": [ 7 | "require-path-exists" 8 | ], 9 | "globals": { 10 | "describe": false, 11 | "it": false, 12 | "before": false, 13 | "after": false, 14 | "beforeEach": false, 15 | "afterEach": false 16 | }, 17 | "rules": { 18 | "array-bracket-spacing": 0 19 | } 20 | } -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: [adrai] # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 13 | -------------------------------------------------------------------------------- /.github/workflows/node.yml: -------------------------------------------------------------------------------- 1 | name: node 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | 8 | jobs: 9 | test: 10 | name: Test on node ${{ matrix.node }} and ${{ matrix.os }} 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | node: [ '14', '12', '10' ] 15 | # os: [ubuntu-latest, windows-latest, macOS-latest] 16 | os: [ubuntu-latest] 17 | steps: 18 | - uses: actions/checkout@v2 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v1 21 | with: 22 | node-version: ${{ matrix.node }} 23 | - run: npm install 24 | - run: npm test -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | $ cat .gitignore 2 | 3 | # Can ignore specific files 4 | .idea 5 | 6 | # Use wildcards as well 7 | *~ 8 | #*.swp 9 | 10 | # Can also ignore all directories and files in a directory. 11 | node_modules 12 | node_modules/**/* 13 | 14 | package-lock.json 15 | 16 | cjs -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | .* 2 | test 3 | dist 4 | .gitignore 5 | .editorconfig 6 | .eslintignore 7 | .eslintrc 8 | .travis.yml 9 | package-lock.json 10 | README.md 11 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: node_js 3 | node_js: 4 | - '8' 5 | - '10' 6 | - '12' 7 | - '14' 8 | branches: 9 | only: 10 | - master 11 | notifications: 12 | email: 13 | - adriano@raiano.ch -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Introduction 2 | 3 | [![Actions](https://github.com/adrai/enum/workflows/node/badge.svg)](https://github.com/adrai/enum/actions?query=workflow%3Anode) 4 | [![travis](https://img.shields.io/travis/adrai/enum.svg)](https://travis-ci.org/adrai/enum) 5 | [![npm](https://img.shields.io/npm/v/enum.svg)](https://npmjs.org/package/enum) 6 | 7 | Enum is a javascript module that introduces the Enum Type. It works for node.js, in the browser and for deno. 8 | 9 | ...and [ref](https://github.com/TooTallNate/ref) compatible [Known Types](https://github.com/TooTallNate/ref/wiki/Known-%22types%22) 10 | 11 | # Download 12 | Releases for a browser are available for download from GitHub. 13 | 14 | | **Version** | **Description** | **Size** | 15 | |:------------|:----------------|:---------| 16 | | `enum-3.0.4.js` | *uncompressed, with comments* | [Download](https://raw.github.com/adrai/enum/master/dist/enum-3.0.4.js) | 17 | | `enum-3.0.4.min.js` | *compressed, without comments* | [Download](https://raw.github.com/adrai/enum/master/dist/enum-3.0.4.min.js) | 18 | 19 | # Installation (node.js) 20 | 21 | $ npm install enum 22 | 23 | # Installation (browser) 24 | 25 | [download](#download) the standalone file 26 | 27 | # Usage 28 | 29 | ````js 30 | // use it as module 31 | const Enum = require('enum') 32 | 33 | // or with import 34 | import Enum from 'enum' 35 | 36 | // or in deno 37 | import Enum from 'https://deno.land/x/enum/index.js' 38 | 39 | // or in browser 40 | 41 | 42 | // or extend node.js, deno or browser global/window with this new type 43 | Enum.register() 44 | 45 | // define a simple enum (automatically flaggable -> A: 0x01, B: 0x02, C: 0x04) 46 | //Uses bitwise 'OR' operation in between the values and creates enumerated constants. For example, if 'Read':1, 'Write':2, then ReadWrite= Read | Write = 1 | 2 = 3 47 | const myEnum = new Enum(['A', 'B', 'C']) 48 | 49 | //define a flagged enum object to create a multicolor option just pass an array 50 | const myEnum = new Enum(['Black', 'Red', 'Green', 'Blue']) 51 | myEnum //=> Enum {_options: Object, enums: Array[4], Black: EnumItem, Red: EnumItem, Green: EnumItem….....} 52 | myEnum.isFlaggable //=> true 53 | 54 | for (let i=1; i<8; i++){ console.log(myEnum.get(i).value + '=> '+ myEnum.get(i).key)} 55 | 1=> Black 56 | 2=> Red 57 | 3=> Black | Red 58 | 4=> Green 59 | 5=> Black | Green 60 | 6=> Red | Green 61 | 7=> Black | Red | Green 62 | 63 | // define an enum with own values 64 | const myEnum = new Enum({'A': 1, 'B': 2, 'C': 4}) 65 | 66 | // if defining a flaggable enum, you can define your own separator (default is ' | ') 67 | const myEnum = new Enum(['A', 'B', 'C'], { separator: ' | ' }) 68 | 69 | // if you want your enum to have a name define it in the options 70 | const myEnum = new Enum(['A', 'B', 'C'], { name: 'MyEnum' }) 71 | 72 | // or 73 | const myEnum = new Enum(['A', 'B', 'C'], 'MyEnum') 74 | 75 | // if you want your enum to have an explicit "endianness", define it in the options 76 | // (defaults to `os.endianness()`) 77 | const myEnum = new Enum(['A', 'B', 'C'], { endianness: 'BE' }) 78 | 79 | // if you want your enum to be not case sensitive 80 | // (defaults to `false`) 81 | const myEnum = new Enum(['One', 'tWo', 'ThrEE'], { ignoreCase: true }) 82 | myEnum.get('one') // => myEnum.One 83 | myEnum.get('TWO') // => myEnum.tWo 84 | myEnum.ThrEE.is('three') // => true 85 | 86 | // this option will make instances of Enum non-extensible 87 | // (defaults to `false`) 88 | const myEnum = new Enum(['ONE', 'TWO', 'THREE'], { freeze: true }) 89 | 90 | //define enum type without flag 91 | const myEnum = new Enum({'None': 0, 'Black':1, 'Red': 2, 'Red2': 3, 'Green': 4, 'Blue': 5}) 92 | myEnum //=> Enum {_options: Object, enums: Array[6], None: EnumItem, Black: EnumItem, Red: EnumItem…........} 93 | myEnum.isFlaggable //=> false 94 | 95 | myEnum.toJSON() // returns {'None': 0, 'Black':1, 'Red': 2, 'Red2': 3, 'Green': 4, 'Blue': 5} 96 | JSON.stringify(myEnum) // returns '{"None":0,"Black":1,"Red":2,"Red2":3,"Green":4,"Blue":5}' 97 | 98 | for(const i=0 i<=5 i++){ console.log(myEnum.get(i).value + '=> '+ myEnum.get(i).key)} 99 | 0=> None 100 | 1=> Black 101 | 2=> Red 102 | 3=> Red2 103 | 4=> Green 104 | 5=> Blue 105 | 106 | // iterating over an enum 107 | myEnum.enums.forEach(function(enumItem) { 108 | console.log(enumItem.key) 109 | }) 110 | // => None 111 | // => Black 112 | // => Red 113 | // => Red2 114 | // => Green 115 | // => Blue 116 | 117 | // get your item 118 | myEnum.A 119 | 120 | // or 121 | myEnum.get('A') 122 | 123 | // or 124 | myEnum.get(1) 125 | 126 | // or 127 | myEnum.get('A | B') 128 | 129 | // or 130 | myEnum.get(3) 131 | 132 | 133 | // get your value 134 | myEnum.A.value 135 | 136 | // get your key 137 | myEnum.A.key 138 | 139 | 140 | // get all items 141 | myEnum.enums // returns all enums in an array 142 | 143 | // check if it's defined 144 | myEnum.isDefined(myEnum.A) // returns true 145 | myEnum.isDefined('A') // returns true 146 | myEnum.isDefined(1) // returns true 147 | 148 | // compare 149 | myEnum.A.is(myEnum.A) 150 | 151 | // or 152 | myEnum.A.is('A') 153 | 154 | // or 155 | myEnum.A.is(1) 156 | 157 | // or 158 | myEnum.A == myEnum.A 159 | 160 | // or 161 | myEnum.A === myEnum.A 162 | 163 | 164 | // check flag 165 | const myItem = myEnum.get(3) // or [myEnum.get('A | B')] 166 | myItem.has(myEnum.A) 167 | 168 | // or 169 | myItem.has('A') 170 | 171 | // or 172 | myItem.has(1) 173 | 174 | 175 | // other functions 176 | myItem.toString() // returns 'A | C' 177 | myItem.toJSON() // returns '"A | C"' 178 | myItem.valueOf() // returns 3 179 | 180 | JSON.stringify(myItem) // returns '"A | C"' 181 | 182 | //Type Safety: 183 | //Newly created enumerable objects are Type-Safe in a way that it's non-configurable and no longer extensible. 184 | //Each EnumItem has a beack-reference to a constructor and they are implicitly final. 185 | Object.getOwnPropertyDescriptor(myEnum, 'Red') //=> Object {value: EnumItem, writable: false, enumerable: true, configurable: false} 186 | Object.isExtensible(myEnum) //=> false 187 | myEnum instanceof Enum //=> true 188 | 189 | //Instances of Enum created with 'new' from similar objects are not equal 190 | myEnum1=new Enum({'A':1, 'B':2, 'C':4}) 191 | myEnum2=new Enum({'A':1, 'B':2, 'C':4}) 192 | myEnum1 == myEnum2 //=> false 193 | myEnum1.A == myEnum2.A //=> false 194 | myEnum1.A.value == myEnum2.A.value //=> true 195 | 196 | //This enum object has no properties other than those defined during its creation. Existing Data is 'Persistent' and preserves the original version 197 | myEnum.B.value //=> 2 198 | myEnum.B = 5 //=> Throws TypeError 199 | delete myEnum.B //=> false 200 | myEnum.D = 6 //=> doesn't add to the enum object, silently ignores 201 | myEnum.D // undefined 202 | 203 | //Try to define new property throws TypeError 204 | Object.defineProperty(myEnum, D, { value:6, writable:false, enumerable:true }) 205 | //=>TypeError: Cannot define property:D, object is not extensible. 206 | ```` -------------------------------------------------------------------------------- /dist/enum-3.0.4.js: -------------------------------------------------------------------------------- 1 | (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Enum = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i= 0) { 190 | return key; 191 | } 192 | 193 | if (!this.isFlaggable || this.isFlaggable && key.key.indexOf(this._options.separator) < 0) { 194 | return; 195 | } 196 | 197 | return this.get(key.key); 198 | } else if ((0, _isType.isString)(key)) { 199 | var enums = this; 200 | 201 | if (this._options.ignoreCase) { 202 | enums = this.getLowerCaseEnums(); 203 | key = key.toLowerCase(); 204 | } 205 | 206 | if (key.indexOf(this._options.separator) > 0) { 207 | var parts = key.split(this._options.separator); 208 | var value = 0; 209 | 210 | for (var i = 0; i < parts.length; i++) { 211 | var part = parts[i]; 212 | value |= enums[part].value; 213 | } 214 | 215 | return new _enumItem["default"](key, value); 216 | } else { 217 | return enums[key]; 218 | } 219 | } else { 220 | for (var m in this) { 221 | // eslint-disable-next-line no-prototype-builtins 222 | if (this.hasOwnProperty(m)) { 223 | if (this[m].value === key) { 224 | return this[m]; 225 | } 226 | } 227 | } 228 | 229 | var result = null; 230 | 231 | if (this.isFlaggable) { 232 | for (var n in this) { 233 | // eslint-disable-next-line no-prototype-builtins 234 | if (this.hasOwnProperty(n)) { 235 | if ((key & this[n].value) !== 0) { 236 | if (result) { 237 | result += this._options.separator; 238 | } else { 239 | result = ''; 240 | } 241 | 242 | result += n; 243 | } 244 | } 245 | } 246 | } 247 | 248 | return this.get(result || null); 249 | } 250 | } 251 | /** 252 | * Sets the Enum "value" onto the give `buffer` at the specified `offset`. 253 | * Part of the ref "Type interface". 254 | * 255 | * @param {Buffer} buffer The Buffer instance to write to. 256 | * @param {Number} offset The offset in the buffer to write to. Default 0. 257 | * @param {EnumItem || String || Number} value The EnumItem to write. 258 | */ 259 | 260 | }, { 261 | key: "set", 262 | value: function set(buffer, offset, value) { 263 | var item = this.get(value); 264 | 265 | if (item) { 266 | return buffer['writeUInt32' + this._options.endianness](item.value, offset || 0); 267 | } 268 | } 269 | /** 270 | * Define freezeEnums() as a property of the prototype. 271 | * make enumerable items nonconfigurable and deep freeze the properties. Throw Error on property setter. 272 | */ 273 | 274 | }, { 275 | key: "freezeEnums", 276 | value: function freezeEnums() { 277 | function envSupportsFreezing() { 278 | return Object.isFrozen && Object.isSealed && Object.getOwnPropertyNames && Object.getOwnPropertyDescriptor && Object.defineProperties && Object.__defineGetter__ && Object.__defineSetter__; 279 | } 280 | 281 | function freezer(o) { 282 | var props = Object.getOwnPropertyNames(o); 283 | props.forEach(function (p) { 284 | if (!Object.getOwnPropertyDescriptor(o, p).configurable) { 285 | return; 286 | } 287 | 288 | Object.defineProperties(o, p, { 289 | writable: false, 290 | configurable: false 291 | }); 292 | }); 293 | return o; 294 | } 295 | 296 | function getPropertyValue(value) { 297 | return value; 298 | } 299 | 300 | function deepFreezeEnums(o) { 301 | if (_typeof(o) !== 'object' || o === null || Object.isFrozen(o) || Object.isSealed(o)) { 302 | return; 303 | } 304 | 305 | for (var key in o) { 306 | // eslint-disable-next-line no-prototype-builtins 307 | if (o.hasOwnProperty(key)) { 308 | o.__defineGetter__(key, getPropertyValue.bind(null, o[key])); 309 | 310 | o.__defineSetter__(key, function throwPropertySetError(value) { 311 | throw TypeError('Cannot redefine property; Enum Type is not extensible.'); 312 | }); 313 | 314 | deepFreezeEnums(o[key]); 315 | } 316 | } 317 | 318 | if (Object.freeze) { 319 | Object.freeze(o); 320 | } else { 321 | freezer(o); 322 | } 323 | } 324 | 325 | if (envSupportsFreezing()) { 326 | deepFreezeEnums(this); 327 | } 328 | 329 | return this; 330 | } 331 | /** 332 | * Return true whether the enumItem parameter passed in is an EnumItem object and 333 | * has been included as constant of this Enum 334 | * @param {EnumItem} enumItem 335 | */ 336 | 337 | }, { 338 | key: "isDefined", 339 | value: function isDefined(enumItem) { 340 | var condition = function condition(e) { 341 | return e === enumItem; 342 | }; 343 | 344 | if ((0, _isType.isString)(enumItem) || (0, _isType.isNumber)(enumItem)) { 345 | condition = function condition(e) { 346 | return e.is(enumItem); 347 | }; 348 | } 349 | 350 | return this.enums.some(condition); 351 | } 352 | /** 353 | * Returns JSON object representation of this Enum. 354 | * @return {String} JSON object representation of this Enum. 355 | */ 356 | 357 | }, { 358 | key: "toJSON", 359 | value: function toJSON() { 360 | return this._enumMap; 361 | } 362 | /** 363 | * Extends the existing Enum with a New Map. 364 | * @param {Array} map Map to extend from 365 | */ 366 | 367 | }, { 368 | key: "extend", 369 | value: function extend(map) { 370 | if (map.length) { 371 | var array = map; 372 | map = {}; 373 | 374 | for (var i = 0; i < array.length; i++) { 375 | var exponent = this._enumLastIndex + i; 376 | map[array[i]] = Math.pow(2, exponent); 377 | } 378 | 379 | for (var member in map) { 380 | guardReservedKeys(this._options.name, member); 381 | this[member] = new _enumItem["default"](member, map[member], { 382 | ignoreCase: this._options.ignoreCase 383 | }); 384 | this.enums.push(this[member]); 385 | } 386 | 387 | for (var key in this._enumMap) { 388 | map[key] = this._enumMap[key]; 389 | } 390 | 391 | this._enumLastIndex += map.length; 392 | this._enumMap = map; 393 | 394 | if (this._options.freeze) { 395 | this.freezeEnums(); // this will make instances of new Enum non-extensible 396 | } 397 | } 398 | } 399 | }, { 400 | key: Symbol.iterator, 401 | value: function value() { 402 | var _this2 = this; 403 | 404 | var index = 0; 405 | return { 406 | next: function next() { 407 | return index < _this2.enums.length ? { 408 | done: false, 409 | value: _this2.enums[index++] 410 | } : { 411 | done: true 412 | }; 413 | } 414 | }; 415 | } 416 | }], [{ 417 | key: "register", 418 | 419 | /** 420 | * Registers the Enum Type globally in node.js. 421 | * @param {String} key Global variable. [optional] 422 | */ 423 | value: function register() { 424 | var key = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 'Enum'; 425 | 426 | if (typeof global !== 'undefined' && !global[key]) { 427 | global[key] = Enum; 428 | } else if (typeof window !== 'undefined' && !window[key]) { 429 | window[key] = Enum; 430 | } 431 | } 432 | }]); 433 | 434 | return Enum; 435 | }(); 436 | 437 | exports["default"] = Enum; 438 | ; // private 439 | 440 | var reservedKeys = ['_options', 'get', 'getKey', 'getValue', 'enums', 'isFlaggable', '_enumMap', 'toJSON', '_enumLastIndex']; 441 | 442 | function guardReservedKeys(customName, key) { 443 | if (customName && key === 'name' || _indexOf.indexOf.call(reservedKeys, key) >= 0) { 444 | throw new Error("Enum key ".concat(key, " is a reserved word!")); 445 | } 446 | } 447 | 448 | module.exports = exports.default; 449 | }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) 450 | },{"./enumItem.js":2,"./indexOf.js":3,"./isType.js":4}],2:[function(require,module,exports){ 451 | "use strict"; 452 | 453 | Object.defineProperty(exports, "__esModule", { 454 | value: true 455 | }); 456 | exports["default"] = void 0; 457 | 458 | var _isType = require("./isType.js"); 459 | 460 | function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } 461 | 462 | function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } 463 | 464 | function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } 465 | 466 | /** 467 | * Represents an Item of an Enum. 468 | * @param {String} key The Enum key. 469 | * @param {Number} value The Enum value. 470 | */ 471 | var EnumItem = /*#__PURE__*/function () { 472 | /* constructor reference so that, this.constructor===EnumItem//=>true */ 473 | function EnumItem(key, value) { 474 | var options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {}; 475 | 476 | _classCallCheck(this, EnumItem); 477 | 478 | this.key = key; 479 | this.value = value; 480 | this._options = options; 481 | this._options.ignoreCase = this._options.ignoreCase || false; 482 | } 483 | /** 484 | * Checks if the flagged EnumItem has the passing object. 485 | * @param {EnumItem || String || Number} value The object to check with. 486 | * @return {Boolean} The check result. 487 | */ 488 | 489 | 490 | _createClass(EnumItem, [{ 491 | key: "has", 492 | value: function has(value) { 493 | if (EnumItem.isEnumItem(value)) { 494 | return (this.value & value.value) !== 0; 495 | } else if ((0, _isType.isString)(value)) { 496 | if (this._options.ignoreCase) { 497 | return this.key.toLowerCase().indexOf(value.toLowerCase()) >= 0; 498 | } 499 | 500 | return this.key.indexOf(value) >= 0; 501 | } else { 502 | return (this.value & value) !== 0; 503 | } 504 | } 505 | /** 506 | * Checks if the EnumItem is the same as the passing object. 507 | * @param {EnumItem || String || Number} key The object to check with. 508 | * @return {Boolean} The check result. 509 | */ 510 | 511 | }, { 512 | key: "is", 513 | value: function is(key) { 514 | if (EnumItem.isEnumItem(key)) { 515 | return this.key === key.key; 516 | } else if ((0, _isType.isString)(key)) { 517 | if (this._options.ignoreCase) { 518 | return this.key.toLowerCase() === key.toLowerCase(); 519 | } 520 | 521 | return this.key === key; 522 | } else { 523 | return this.value === key; 524 | } 525 | } 526 | /** 527 | * Returns String representation of this EnumItem. 528 | * @return {String} String representation of this EnumItem. 529 | */ 530 | 531 | }, { 532 | key: "toString", 533 | value: function toString() { 534 | return this.key; 535 | } 536 | /** 537 | * Returns JSON object representation of this EnumItem. 538 | * @return {String} JSON object representation of this EnumItem. 539 | */ 540 | 541 | }, { 542 | key: "toJSON", 543 | value: function toJSON() { 544 | return this.key; 545 | } 546 | /** 547 | * Returns the value to compare with. 548 | * @return {String} The value to compare with. 549 | */ 550 | 551 | }, { 552 | key: "valueOf", 553 | value: function valueOf() { 554 | return this.value; 555 | } 556 | }], [{ 557 | key: "isEnumItem", 558 | value: function isEnumItem(value) { 559 | return value instanceof EnumItem || (0, _isType.isObject)(value) && value.key !== undefined && value.value !== undefined; 560 | } 561 | }]); 562 | 563 | return EnumItem; 564 | }(); 565 | 566 | exports["default"] = EnumItem; 567 | ; 568 | module.exports = exports.default; 569 | },{"./isType.js":4}],3:[function(require,module,exports){ 570 | "use strict"; 571 | 572 | Object.defineProperty(exports, "__esModule", { 573 | value: true 574 | }); 575 | exports.indexOf = void 0; 576 | 577 | var indexOf = Array.prototype.indexOf || function (find, i 578 | /* opt */ 579 | ) { 580 | if (i === undefined) i = 0; 581 | if (i < 0) i += this.length; 582 | if (i < 0) i = 0; 583 | 584 | for (var n = this.length; i < n; i++) { 585 | if (i in this && this[i] === find) { 586 | return i; 587 | } 588 | } 589 | 590 | return -1; 591 | }; 592 | 593 | exports.indexOf = indexOf; 594 | },{}],4:[function(require,module,exports){ 595 | "use strict"; 596 | 597 | Object.defineProperty(exports, "__esModule", { 598 | value: true 599 | }); 600 | exports.isNumber = exports.isString = exports.isObject = exports.isType = void 0; 601 | 602 | function _typeof(obj) { "@babel/helpers - typeof"; if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } 603 | 604 | // eslint-disable-next-line valid-typeof 605 | var isType = function isType(type, value) { 606 | return _typeof(value) === type; 607 | }; 608 | 609 | exports.isType = isType; 610 | 611 | var isObject = function isObject(value) { 612 | return isType('object', value); 613 | }; 614 | 615 | exports.isObject = isObject; 616 | 617 | var isString = function isString(value) { 618 | return isType('string', value); 619 | }; 620 | 621 | exports.isString = isString; 622 | 623 | var isNumber = function isNumber(value) { 624 | return isType('number', value); 625 | }; 626 | 627 | exports.isNumber = isNumber; 628 | },{}]},{},[1])(1) 629 | }); 630 | -------------------------------------------------------------------------------- /dist/enum-3.0.4.min.js: -------------------------------------------------------------------------------- 1 | !function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Enum=e()}}(function(){return function o(s,u,a){function f(t,e){if(!u[t]){if(!s[t]){var n="function"==typeof require&&require;if(!e&&n)return n(t,!0);if(l)return l(t,!0);var i=new Error("Cannot find module '"+t+"'");throw i.code="MODULE_NOT_FOUND",i}var r=u[t]={exports:{}};s[t][0].call(r.exports,function(e){return f(s[t][1][e]||e)},r,r.exports,o,s,u,a)}return u[t].exports}for(var l="function"==typeof require&&require,e=0;e { 6 | return obj != null && obj.constructor != null && 7 | typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj) 8 | } 9 | 10 | /** 11 | * Returns a string identifying the endianness of the CPU for which the Deno 12 | * binary was compiled. Possible values are 'BE' for big endian and 'LE' for 13 | * little endian. 14 | **/ 15 | const getEndianess = () => { 16 | // Source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView#Endianness 17 | const buffer = new ArrayBuffer(2) 18 | new DataView(buffer).setInt16(0, 256, true /* littleEndian */) 19 | // Int16Array uses the platform's endianness. 20 | return new Int16Array(buffer)[0] === 256 ? 'LE' : 'BE' 21 | } 22 | 23 | const endianness = getEndianess() 24 | 25 | /** 26 | * Represents an Enum with enum items. 27 | * @param {Array || Object} map This are the enum items. 28 | * @param {String || Object} options This are options. [optional] 29 | */ 30 | export default class Enum { 31 | constructor (map, options) { 32 | /* implement the "ref type interface", so that Enum types can 33 | * be used in `node-ffi` function declarations and invokations. 34 | * In C, these Enums act as `uint32_t` types. 35 | * 36 | * https://github.com/TooTallNate/ref#the-type-interface 37 | */ 38 | this.size = 4 39 | this.indirection = 1 40 | 41 | if (options && isString(options)) { 42 | options = { name: options } 43 | } 44 | 45 | this._options = options || {} 46 | this._options.separator = this._options.separator || ' | ' 47 | this._options.endianness = this._options.endianness || endianness 48 | this._options.ignoreCase = this._options.ignoreCase || false 49 | this._options.freez = this._options.freez || false // backword compatability 50 | this._options.freeze = this._options.freeze || this._options.freez || false 51 | 52 | this.enums = [] 53 | 54 | if (map.length) { 55 | this._enumLastIndex = map.length 56 | var array = map 57 | map = {} 58 | 59 | for (var i = 0; i < array.length; i++) { 60 | map[array[i]] = Math.pow(2, i) 61 | } 62 | } 63 | 64 | for (var member in map) { 65 | guardReservedKeys(this._options.name, member) 66 | this[member] = new EnumItem(member, map[member], { ignoreCase: this._options.ignoreCase }) 67 | this.enums.push(this[member]) 68 | } 69 | this._enumMap = map 70 | 71 | if (this._options.ignoreCase) { 72 | this.getLowerCaseEnums = function () { 73 | var res = {} 74 | for (var i = 0, len = this.enums.length; i < len; i++) { 75 | res[this.enums[i].key.toLowerCase()] = this.enums[i] 76 | } 77 | return res 78 | } 79 | } 80 | 81 | if (this._options.name) { 82 | this.name = this._options.name 83 | } 84 | 85 | const isFlaggable = () => { 86 | for (var i = 0, len = this.enums.length; i < len; i++) { 87 | var e = this.enums[i] 88 | 89 | if (!(e.value !== 0 && !(e.value & e.value - 1))) { 90 | return false 91 | } 92 | } 93 | return true 94 | } 95 | 96 | this.isFlaggable = isFlaggable() 97 | if (this._options.freeze) { 98 | this.freezeEnums() // this will make instances of Enum non-extensible 99 | } 100 | } 101 | 102 | /** 103 | * Returns the appropriate EnumItem key. 104 | * @param {EnumItem || String || Number} key The object to get with. 105 | * @return {String} The get result. 106 | */ 107 | getKey (value) { 108 | var item = this.get(value) 109 | if (item) { 110 | return item.key 111 | } 112 | } 113 | 114 | /** 115 | * Returns the appropriate EnumItem value. 116 | * @param {EnumItem || String || Number} key The object to get with. 117 | * @return {Number} The get result. 118 | */ 119 | getValue (key) { 120 | var item = this.get(key) 121 | if (item) { 122 | return item.value 123 | } 124 | } 125 | 126 | /** 127 | * Returns the appropriate EnumItem. 128 | * @param {EnumItem || String || Number} key The object to get with. 129 | * @return {EnumItem} The get result. 130 | */ 131 | get (key, offset) { 132 | if (key === null || key === undefined) { 133 | return 134 | } // Buffer instance support, part of the ref Type interface 135 | if (isBuffer(key)) { 136 | key = key['readUInt32' + this._options.endianness](offset || 0) 137 | } 138 | 139 | if (EnumItem.isEnumItem(key)) { 140 | var foundIndex = indexOf.call(this.enums, key) 141 | if (foundIndex >= 0) { 142 | return key 143 | } 144 | if (!this.isFlaggable || (this.isFlaggable && key.key.indexOf(this._options.separator) < 0)) { 145 | return 146 | } 147 | return this.get(key.key) 148 | } else if (isString(key)) { 149 | var enums = this 150 | if (this._options.ignoreCase) { 151 | enums = this.getLowerCaseEnums() 152 | key = key.toLowerCase() 153 | } 154 | 155 | if (key.indexOf(this._options.separator) > 0) { 156 | var parts = key.split(this._options.separator) 157 | 158 | var value = 0 159 | for (var i = 0; i < parts.length; i++) { 160 | var part = parts[i] 161 | 162 | value |= enums[part].value 163 | } 164 | 165 | return new EnumItem(key, value) 166 | } else { 167 | return enums[key] 168 | } 169 | } else { 170 | for (var m in this) { 171 | // eslint-disable-next-line no-prototype-builtins 172 | if (this.hasOwnProperty(m)) { 173 | if (this[m].value === key) { 174 | return this[m] 175 | } 176 | } 177 | } 178 | 179 | var result = null 180 | 181 | if (this.isFlaggable) { 182 | for (var n in this) { 183 | // eslint-disable-next-line no-prototype-builtins 184 | if (this.hasOwnProperty(n)) { 185 | if ((key & this[n].value) !== 0) { 186 | if (result) { 187 | result += this._options.separator 188 | } else { 189 | result = '' 190 | } 191 | result += n 192 | } 193 | } 194 | } 195 | } 196 | 197 | return this.get(result || null) 198 | } 199 | } 200 | 201 | /** 202 | * Sets the Enum "value" onto the give `buffer` at the specified `offset`. 203 | * Part of the ref "Type interface". 204 | * 205 | * @param {Buffer} buffer The Buffer instance to write to. 206 | * @param {Number} offset The offset in the buffer to write to. Default 0. 207 | * @param {EnumItem || String || Number} value The EnumItem to write. 208 | */ 209 | set (buffer, offset, value) { 210 | var item = this.get(value) 211 | if (item) { 212 | return buffer['writeUInt32' + this._options.endianness](item.value, offset || 0) 213 | } 214 | } 215 | 216 | /** 217 | * Define freezeEnums() as a property of the prototype. 218 | * make enumerable items nonconfigurable and deep freeze the properties. Throw Error on property setter. 219 | */ 220 | freezeEnums () { 221 | function envSupportsFreezing () { 222 | return ( 223 | Object.isFrozen && Object.isSealed && 224 | Object.getOwnPropertyNames && Object.getOwnPropertyDescriptor && 225 | Object.defineProperties && Object.__defineGetter__ && Object.__defineSetter__ 226 | ) 227 | } 228 | 229 | function freezer (o) { 230 | var props = Object.getOwnPropertyNames(o) 231 | props.forEach(function (p) { 232 | if (!Object.getOwnPropertyDescriptor(o, p).configurable) { 233 | return 234 | } 235 | 236 | Object.defineProperties(o, p, { writable: false, configurable: false }) 237 | }) 238 | return o 239 | } 240 | 241 | function getPropertyValue (value) { 242 | return value 243 | } 244 | 245 | function deepFreezeEnums (o) { 246 | if (typeof o !== 'object' || o === null || Object.isFrozen(o) || Object.isSealed(o)) { 247 | return 248 | } 249 | for (var key in o) { 250 | // eslint-disable-next-line no-prototype-builtins 251 | if (o.hasOwnProperty(key)) { 252 | o.__defineGetter__(key, getPropertyValue.bind(null, o[key])) 253 | o.__defineSetter__(key, function throwPropertySetError (value) { 254 | throw TypeError('Cannot redefine property; Enum Type is not extensible.') 255 | }) 256 | deepFreezeEnums(o[key]) 257 | } 258 | } 259 | if (Object.freeze) { 260 | Object.freeze(o) 261 | } else { 262 | freezer(o) 263 | } 264 | } 265 | 266 | if (envSupportsFreezing()) { 267 | deepFreezeEnums(this) 268 | } 269 | 270 | return this 271 | } 272 | 273 | /** 274 | * Return true whether the enumItem parameter passed in is an EnumItem object and 275 | * has been included as constant of this Enum 276 | * @param {EnumItem} enumItem 277 | */ 278 | isDefined (enumItem) { 279 | let condition = (e) => e === enumItem 280 | if (isString(enumItem) || isNumber(enumItem)) { 281 | condition = (e) => e.is(enumItem) 282 | } 283 | return this.enums.some(condition) 284 | } 285 | 286 | /** 287 | * Returns JSON object representation of this Enum. 288 | * @return {String} JSON object representation of this Enum. 289 | */ 290 | toJSON () { 291 | return this._enumMap 292 | } 293 | 294 | /** 295 | * Extends the existing Enum with a New Map. 296 | * @param {Array} map Map to extend from 297 | */ 298 | extend (map) { 299 | if (map.length) { 300 | var array = map 301 | map = {} 302 | 303 | for (var i = 0; i < array.length; i++) { 304 | var exponent = this._enumLastIndex + i 305 | map[array[i]] = Math.pow(2, exponent) 306 | } 307 | 308 | for (var member in map) { 309 | guardReservedKeys(this._options.name, member) 310 | this[member] = new EnumItem(member, map[member], { ignoreCase: this._options.ignoreCase }) 311 | this.enums.push(this[member]) 312 | } 313 | 314 | for (var key in this._enumMap) { 315 | map[key] = this._enumMap[key] 316 | } 317 | 318 | this._enumLastIndex += map.length 319 | this._enumMap = map 320 | 321 | if (this._options.freeze) { 322 | this.freezeEnums() // this will make instances of new Enum non-extensible 323 | } 324 | } 325 | }; 326 | 327 | /** 328 | * Registers the Enum Type globally in node.js. 329 | * @param {String} key Global variable. [optional] 330 | */ 331 | static register (key = 'Enum') { 332 | if (typeof global !== 'undefined' && !global[key]) { 333 | global[key] = Enum 334 | } else if (typeof window !== 'undefined' && !window[key]) { 335 | window[key] = Enum 336 | } 337 | } 338 | 339 | [Symbol.iterator] () { 340 | let index = 0 341 | return { 342 | next: () => index < this.enums.length ? { done: false, value: this.enums[index++] } : { done: true } 343 | } 344 | } 345 | }; 346 | 347 | // private 348 | 349 | var reservedKeys = ['_options', 'get', 'getKey', 'getValue', 'enums', 'isFlaggable', '_enumMap', 'toJSON', '_enumLastIndex'] 350 | 351 | function guardReservedKeys (customName, key) { 352 | if ((customName && key === 'name') || indexOf.call(reservedKeys, key) >= 0) { 353 | throw new Error(`Enum key ${key} is a reserved word!`) 354 | } 355 | } 356 | -------------------------------------------------------------------------------- /lib/enumItem.js: -------------------------------------------------------------------------------- 1 | import { isObject, isString } from './isType.js' 2 | 3 | /** 4 | * Represents an Item of an Enum. 5 | * @param {String} key The Enum key. 6 | * @param {Number} value The Enum value. 7 | */ 8 | export default class EnumItem { 9 | /* constructor reference so that, this.constructor===EnumItem//=>true */ 10 | constructor (key, value, options = {}) { 11 | this.key = key 12 | this.value = value 13 | 14 | this._options = options 15 | this._options.ignoreCase = this._options.ignoreCase || false 16 | } 17 | 18 | /** 19 | * Checks if the flagged EnumItem has the passing object. 20 | * @param {EnumItem || String || Number} value The object to check with. 21 | * @return {Boolean} The check result. 22 | */ 23 | has (value) { 24 | if (EnumItem.isEnumItem(value)) { 25 | return (this.value & value.value) !== 0 26 | } else if (isString(value)) { 27 | if (this._options.ignoreCase) { 28 | return this.key.toLowerCase().indexOf(value.toLowerCase()) >= 0 29 | } 30 | return this.key.indexOf(value) >= 0 31 | } else { 32 | return (this.value & value) !== 0 33 | } 34 | } 35 | 36 | /** 37 | * Checks if the EnumItem is the same as the passing object. 38 | * @param {EnumItem || String || Number} key The object to check with. 39 | * @return {Boolean} The check result. 40 | */ 41 | is (key) { 42 | if (EnumItem.isEnumItem(key)) { 43 | return this.key === key.key 44 | } else if (isString(key)) { 45 | if (this._options.ignoreCase) { 46 | return this.key.toLowerCase() === key.toLowerCase() 47 | } 48 | return this.key === key 49 | } else { 50 | return this.value === key 51 | } 52 | } 53 | 54 | /** 55 | * Returns String representation of this EnumItem. 56 | * @return {String} String representation of this EnumItem. 57 | */ 58 | toString () { 59 | return this.key 60 | } 61 | 62 | /** 63 | * Returns JSON object representation of this EnumItem. 64 | * @return {String} JSON object representation of this EnumItem. 65 | */ 66 | toJSON () { 67 | return this.key 68 | } 69 | 70 | /** 71 | * Returns the value to compare with. 72 | * @return {String} The value to compare with. 73 | */ 74 | valueOf () { 75 | return this.value 76 | } 77 | 78 | static isEnumItem (value) { 79 | return value instanceof EnumItem || (isObject(value) && value.key !== undefined && value.value !== undefined) 80 | } 81 | }; 82 | -------------------------------------------------------------------------------- /lib/indexOf.js: -------------------------------------------------------------------------------- 1 | export const indexOf = Array.prototype.indexOf || function (find, i /* opt */) { 2 | if (i === undefined) i = 0 3 | if (i < 0) i += this.length 4 | if (i < 0) i = 0 5 | for (var n = this.length; i < n; i++) { 6 | if (i in this && this[i] === find) { return i } 7 | } 8 | return -1 9 | } 10 | -------------------------------------------------------------------------------- /lib/isType.js: -------------------------------------------------------------------------------- 1 | // eslint-disable-next-line valid-typeof 2 | export const isType = (type, value) => typeof value === type 3 | export const isObject = (value) => isType('object', value) 4 | export const isString = (value) => isType('string', value) 5 | export const isNumber = (value) => isType('number', value) 6 | -------------------------------------------------------------------------------- /licence: -------------------------------------------------------------------------------- 1 | Copyright (c) 2020 Adriano Raiano, Christoph Hermann 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "adrai", 3 | "name": "enum", 4 | "version": "3.0.4", 5 | "private": false, 6 | "type": "module", 7 | "main": "./cjs/enum.js", 8 | "exports": { 9 | "./package.json": "./package.json", 10 | ".": { 11 | "require": "./cjs/enum.js", 12 | "default": "./lib/enum.js" 13 | } 14 | }, 15 | "module": "./lib/enum.js", 16 | "engines": { 17 | "node": ">=0.6.0" 18 | }, 19 | "dependencies": {}, 20 | "devDependencies": { 21 | "@babel/cli": "7.8.4", 22 | "@babel/core": "7.9.0", 23 | "@babel/preset-env": "7.9.5", 24 | "babel-plugin-add-module-exports": "1.0.2", 25 | "browserify": "16.5.1", 26 | "eslint": "6.8.0", 27 | "eslint-config-standard": "14.1.1", 28 | "eslint-plugin-import": "2.20.1", 29 | "eslint-plugin-node": "11.0.0", 30 | "eslint-plugin-promise": "4.2.1", 31 | "eslint-plugin-require-path-exists": "1.1.9", 32 | "eslint-plugin-standard": "4.0.1", 33 | "expect.js": "0.3.1", 34 | "mocha": "7.1.1", 35 | "uglify-js": "3.8.1" 36 | }, 37 | "description": "Enum is a javascript module that introduces the Enum Type. It works for node.js, in the browser and for deno.", 38 | "keywords": [ 39 | "enum" 40 | ], 41 | "homepage": "https://github.com/adrai/enum", 42 | "repository": { 43 | "type": "git", 44 | "url": "git@github.com:adrai/enum.git" 45 | }, 46 | "bugs": { 47 | "url": "https://github.com/adrai/enum/issues" 48 | }, 49 | "licenses": [ 50 | { 51 | "type": "MIT", 52 | "url": "https://raw.github.com/adrai/enum/master/licence" 53 | } 54 | ], 55 | "scripts": { 56 | "lint": "eslint .", 57 | "compile": "rm -rf cjs && mkdir cjs && babel lib -d cjs --presets=@babel/preset-env --plugins=add-module-exports && echo '{\"type\":\"commonjs\"}' > cjs/package.json", 58 | "browser": "rm -rf dist && mkdir dist && browserify --standalone Enum cjs/enum.js -o dist/enum-$npm_package_version.js && uglifyjs dist/enum-$npm_package_version.js --compress --mangle -o dist/enum-$npm_package_version.min.js", 59 | "build": "npm run compile && npm run browser", 60 | "test": "npm run lint && npm run build && mocha test -R spec --globals Enum" 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /test/buffer.js: -------------------------------------------------------------------------------- 1 | (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o 15 | * @license MIT 16 | */ 17 | 18 | var base64 = require('base64-js') 19 | var ieee754 = require('ieee754') 20 | var isArray = require('is-array') 21 | 22 | exports.Buffer = Buffer 23 | exports.SlowBuffer = SlowBuffer 24 | exports.INSPECT_MAX_BYTES = 50 25 | Buffer.poolSize = 8192 // not used by this implementation 26 | 27 | var kMaxLength = 0x3fffffff 28 | var rootParent = {} 29 | 30 | /** 31 | * If `Buffer.TYPED_ARRAY_SUPPORT`: 32 | * === true Use Uint8Array implementation (fastest) 33 | * === false Use Object implementation (most compatible, even IE6) 34 | * 35 | * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+, 36 | * Opera 11.6+, iOS 4.2+. 37 | * 38 | * Note: 39 | * 40 | * - Implementation must support adding new properties to `Uint8Array` instances. 41 | * Firefox 4-29 lacked support, fixed in Firefox 30+. 42 | * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438. 43 | * 44 | * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function. 45 | * 46 | * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of 47 | * incorrect length in some situations. 48 | * 49 | * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they will 50 | * get the Object implementation, which is slower but will work correctly. 51 | */ 52 | Buffer.TYPED_ARRAY_SUPPORT = (function () { 53 | try { 54 | var buf = new ArrayBuffer(0) 55 | var arr = new Uint8Array(buf) 56 | arr.foo = function () { return 42 } 57 | return arr.foo() === 42 && // typed array instances can be augmented 58 | typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray` 59 | new Uint8Array(1).subarray(1, 1).byteLength === 0 // ie10 has broken `subarray` 60 | } catch (e) { 61 | return false 62 | } 63 | })() 64 | 65 | /** 66 | * Class: Buffer 67 | * ============= 68 | * 69 | * The Buffer constructor returns instances of `Uint8Array` that are augmented 70 | * with function properties for all the node `Buffer` API functions. We use 71 | * `Uint8Array` so that square bracket notation works as expected -- it returns 72 | * a single octet. 73 | * 74 | * By augmenting the instances, we can avoid modifying the `Uint8Array` 75 | * prototype. 76 | */ 77 | function Buffer (subject, encoding, noZero) { 78 | if (!(this instanceof Buffer)) 79 | return new Buffer(subject, encoding, noZero) 80 | 81 | var type = typeof subject 82 | 83 | // Find the length 84 | var length 85 | if (type === 'number') { 86 | length = +subject 87 | } else if (type === 'string') { 88 | length = Buffer.byteLength(subject, encoding) 89 | } else if (type === 'object' && subject !== null) { // assume object is array-like 90 | if (subject.type === 'Buffer' && isArray(subject.data)) 91 | subject = subject.data 92 | length = +subject.length 93 | } else { 94 | throw new TypeError('must start with number, buffer, array or string') 95 | } 96 | 97 | if (length > kMaxLength) 98 | throw new RangeError('Attempt to allocate Buffer larger than maximum ' + 99 | 'size: 0x' + kMaxLength.toString(16) + ' bytes') 100 | 101 | if (length < 0) 102 | length = 0 103 | else 104 | length >>>= 0 // Coerce to uint32. 105 | 106 | var self = this 107 | if (Buffer.TYPED_ARRAY_SUPPORT) { 108 | // Preferred: Return an augmented `Uint8Array` instance for best performance 109 | /*eslint-disable consistent-this */ 110 | self = Buffer._augment(new Uint8Array(length)) 111 | /*eslint-enable consistent-this */ 112 | } else { 113 | // Fallback: Return THIS instance of Buffer (created by `new`) 114 | self.length = length 115 | self._isBuffer = true 116 | } 117 | 118 | var i 119 | if (Buffer.TYPED_ARRAY_SUPPORT && typeof subject.byteLength === 'number') { 120 | // Speed optimization -- use set if we're copying from a typed array 121 | self._set(subject) 122 | } else if (isArrayish(subject)) { 123 | // Treat array-ish objects as a byte array 124 | if (Buffer.isBuffer(subject)) { 125 | for (i = 0; i < length; i++) 126 | self[i] = subject.readUInt8(i) 127 | } else { 128 | for (i = 0; i < length; i++) 129 | self[i] = ((subject[i] % 256) + 256) % 256 130 | } 131 | } else if (type === 'string') { 132 | self.write(subject, 0, encoding) 133 | } else if (type === 'number' && !Buffer.TYPED_ARRAY_SUPPORT && !noZero) { 134 | for (i = 0; i < length; i++) { 135 | self[i] = 0 136 | } 137 | } 138 | 139 | if (length > 0 && length <= Buffer.poolSize) 140 | self.parent = rootParent 141 | 142 | return self 143 | } 144 | 145 | function SlowBuffer (subject, encoding, noZero) { 146 | if (!(this instanceof SlowBuffer)) 147 | return new SlowBuffer(subject, encoding, noZero) 148 | 149 | var buf = new Buffer(subject, encoding, noZero) 150 | delete buf.parent 151 | return buf 152 | } 153 | 154 | Buffer.isBuffer = function (b) { 155 | return !!(b != null && b._isBuffer) 156 | } 157 | 158 | Buffer.compare = function (a, b) { 159 | if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) 160 | throw new TypeError('Arguments must be Buffers') 161 | 162 | if (a === b) return 0 163 | 164 | var x = a.length 165 | var y = b.length 166 | for (var i = 0, len = Math.min(x, y); i < len && a[i] === b[i]; i++) {} 167 | if (i !== len) { 168 | x = a[i] 169 | y = b[i] 170 | } 171 | if (x < y) return -1 172 | if (y < x) return 1 173 | return 0 174 | } 175 | 176 | Buffer.isEncoding = function (encoding) { 177 | switch (String(encoding).toLowerCase()) { 178 | case 'hex': 179 | case 'utf8': 180 | case 'utf-8': 181 | case 'ascii': 182 | case 'binary': 183 | case 'base64': 184 | case 'raw': 185 | case 'ucs2': 186 | case 'ucs-2': 187 | case 'utf16le': 188 | case 'utf-16le': 189 | return true 190 | default: 191 | return false 192 | } 193 | } 194 | 195 | Buffer.concat = function (list, totalLength) { 196 | if (!isArray(list)) throw new TypeError('Usage: Buffer.concat(list[, length])') 197 | 198 | if (list.length === 0) { 199 | return new Buffer(0) 200 | } else if (list.length === 1) { 201 | return list[0] 202 | } 203 | 204 | var i 205 | if (totalLength === undefined) { 206 | totalLength = 0 207 | for (i = 0; i < list.length; i++) { 208 | totalLength += list[i].length 209 | } 210 | } 211 | 212 | var buf = new Buffer(totalLength) 213 | var pos = 0 214 | for (i = 0; i < list.length; i++) { 215 | var item = list[i] 216 | item.copy(buf, pos) 217 | pos += item.length 218 | } 219 | return buf 220 | } 221 | 222 | Buffer.byteLength = function (str, encoding) { 223 | var ret 224 | str = str + '' 225 | switch (encoding || 'utf8') { 226 | case 'ascii': 227 | case 'binary': 228 | case 'raw': 229 | ret = str.length 230 | break 231 | case 'ucs2': 232 | case 'ucs-2': 233 | case 'utf16le': 234 | case 'utf-16le': 235 | ret = str.length * 2 236 | break 237 | case 'hex': 238 | ret = str.length >>> 1 239 | break 240 | case 'utf8': 241 | case 'utf-8': 242 | ret = utf8ToBytes(str).length 243 | break 244 | case 'base64': 245 | ret = base64ToBytes(str).length 246 | break 247 | default: 248 | ret = str.length 249 | } 250 | return ret 251 | } 252 | 253 | // pre-set for values that may exist in the future 254 | Buffer.prototype.length = undefined 255 | Buffer.prototype.parent = undefined 256 | 257 | // toString(encoding, start=0, end=buffer.length) 258 | Buffer.prototype.toString = function (encoding, start, end) { 259 | var loweredCase = false 260 | 261 | start = start >>> 0 262 | end = end === undefined || end === Infinity ? this.length : end >>> 0 263 | 264 | if (!encoding) encoding = 'utf8' 265 | if (start < 0) start = 0 266 | if (end > this.length) end = this.length 267 | if (end <= start) return '' 268 | 269 | while (true) { 270 | switch (encoding) { 271 | case 'hex': 272 | return hexSlice(this, start, end) 273 | 274 | case 'utf8': 275 | case 'utf-8': 276 | return utf8Slice(this, start, end) 277 | 278 | case 'ascii': 279 | return asciiSlice(this, start, end) 280 | 281 | case 'binary': 282 | return binarySlice(this, start, end) 283 | 284 | case 'base64': 285 | return base64Slice(this, start, end) 286 | 287 | case 'ucs2': 288 | case 'ucs-2': 289 | case 'utf16le': 290 | case 'utf-16le': 291 | return utf16leSlice(this, start, end) 292 | 293 | default: 294 | if (loweredCase) 295 | throw new TypeError('Unknown encoding: ' + encoding) 296 | encoding = (encoding + '').toLowerCase() 297 | loweredCase = true 298 | } 299 | } 300 | } 301 | 302 | Buffer.prototype.equals = function (b) { 303 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 304 | if (this === b) return true 305 | return Buffer.compare(this, b) === 0 306 | } 307 | 308 | Buffer.prototype.inspect = function () { 309 | var str = '' 310 | var max = exports.INSPECT_MAX_BYTES 311 | if (this.length > 0) { 312 | str = this.toString('hex', 0, max).match(/.{2}/g).join(' ') 313 | if (this.length > max) 314 | str += ' ... ' 315 | } 316 | return '' 317 | } 318 | 319 | Buffer.prototype.compare = function (b) { 320 | if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer') 321 | if (this === b) return 0 322 | return Buffer.compare(this, b) 323 | } 324 | 325 | // `get` will be removed in Node 0.13+ 326 | Buffer.prototype.get = function (offset) { 327 | console.log('.get() is deprecated. Access using array indexes instead.') 328 | return this.readUInt8(offset) 329 | } 330 | 331 | // `set` will be removed in Node 0.13+ 332 | Buffer.prototype.set = function (v, offset) { 333 | console.log('.set() is deprecated. Access using array indexes instead.') 334 | return this.writeUInt8(v, offset) 335 | } 336 | 337 | function hexWrite (buf, string, offset, length) { 338 | offset = Number(offset) || 0 339 | var remaining = buf.length - offset 340 | if (!length) { 341 | length = remaining 342 | } else { 343 | length = Number(length) 344 | if (length > remaining) { 345 | length = remaining 346 | } 347 | } 348 | 349 | // must be an even number of digits 350 | var strLen = string.length 351 | if (strLen % 2 !== 0) throw new Error('Invalid hex string') 352 | 353 | if (length > strLen / 2) { 354 | length = strLen / 2 355 | } 356 | for (var i = 0; i < length; i++) { 357 | var byte = parseInt(string.substr(i * 2, 2), 16) 358 | if (isNaN(byte)) throw new Error('Invalid hex string') 359 | buf[offset + i] = byte 360 | } 361 | return i 362 | } 363 | 364 | function utf8Write (buf, string, offset, length) { 365 | var charsWritten = blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length) 366 | return charsWritten 367 | } 368 | 369 | function asciiWrite (buf, string, offset, length) { 370 | var charsWritten = blitBuffer(asciiToBytes(string), buf, offset, length) 371 | return charsWritten 372 | } 373 | 374 | function binaryWrite (buf, string, offset, length) { 375 | return asciiWrite(buf, string, offset, length) 376 | } 377 | 378 | function base64Write (buf, string, offset, length) { 379 | var charsWritten = blitBuffer(base64ToBytes(string), buf, offset, length) 380 | return charsWritten 381 | } 382 | 383 | function utf16leWrite (buf, string, offset, length) { 384 | var charsWritten = blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length) 385 | return charsWritten 386 | } 387 | 388 | Buffer.prototype.write = function (string, offset, length, encoding) { 389 | // Support both (string, offset, length, encoding) 390 | // and the legacy (string, encoding, offset, length) 391 | if (isFinite(offset)) { 392 | if (!isFinite(length)) { 393 | encoding = length 394 | length = undefined 395 | } 396 | } else { // legacy 397 | var swap = encoding 398 | encoding = offset 399 | offset = length 400 | length = swap 401 | } 402 | 403 | offset = Number(offset) || 0 404 | 405 | if (length < 0 || offset < 0 || offset > this.length) 406 | throw new RangeError('attempt to write outside buffer bounds') 407 | 408 | var remaining = this.length - offset 409 | if (!length) { 410 | length = remaining 411 | } else { 412 | length = Number(length) 413 | if (length > remaining) { 414 | length = remaining 415 | } 416 | } 417 | encoding = String(encoding || 'utf8').toLowerCase() 418 | 419 | var ret 420 | switch (encoding) { 421 | case 'hex': 422 | ret = hexWrite(this, string, offset, length) 423 | break 424 | case 'utf8': 425 | case 'utf-8': 426 | ret = utf8Write(this, string, offset, length) 427 | break 428 | case 'ascii': 429 | ret = asciiWrite(this, string, offset, length) 430 | break 431 | case 'binary': 432 | ret = binaryWrite(this, string, offset, length) 433 | break 434 | case 'base64': 435 | ret = base64Write(this, string, offset, length) 436 | break 437 | case 'ucs2': 438 | case 'ucs-2': 439 | case 'utf16le': 440 | case 'utf-16le': 441 | ret = utf16leWrite(this, string, offset, length) 442 | break 443 | default: 444 | throw new TypeError('Unknown encoding: ' + encoding) 445 | } 446 | return ret 447 | } 448 | 449 | Buffer.prototype.toJSON = function () { 450 | return { 451 | type: 'Buffer', 452 | data: Array.prototype.slice.call(this._arr || this, 0) 453 | } 454 | } 455 | 456 | function base64Slice (buf, start, end) { 457 | if (start === 0 && end === buf.length) { 458 | return base64.fromByteArray(buf) 459 | } else { 460 | return base64.fromByteArray(buf.slice(start, end)) 461 | } 462 | } 463 | 464 | function utf8Slice (buf, start, end) { 465 | var res = '' 466 | var tmp = '' 467 | end = Math.min(buf.length, end) 468 | 469 | for (var i = start; i < end; i++) { 470 | if (buf[i] <= 0x7F) { 471 | res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]) 472 | tmp = '' 473 | } else { 474 | tmp += '%' + buf[i].toString(16) 475 | } 476 | } 477 | 478 | return res + decodeUtf8Char(tmp) 479 | } 480 | 481 | function asciiSlice (buf, start, end) { 482 | var ret = '' 483 | end = Math.min(buf.length, end) 484 | 485 | for (var i = start; i < end; i++) { 486 | ret += String.fromCharCode(buf[i] & 0x7F) 487 | } 488 | return ret 489 | } 490 | 491 | function binarySlice (buf, start, end) { 492 | var ret = '' 493 | end = Math.min(buf.length, end) 494 | 495 | for (var i = start; i < end; i++) { 496 | ret += String.fromCharCode(buf[i]) 497 | } 498 | return ret 499 | } 500 | 501 | function hexSlice (buf, start, end) { 502 | var len = buf.length 503 | 504 | if (!start || start < 0) start = 0 505 | if (!end || end < 0 || end > len) end = len 506 | 507 | var out = '' 508 | for (var i = start; i < end; i++) { 509 | out += toHex(buf[i]) 510 | } 511 | return out 512 | } 513 | 514 | function utf16leSlice (buf, start, end) { 515 | var bytes = buf.slice(start, end) 516 | var res = '' 517 | for (var i = 0; i < bytes.length; i += 2) { 518 | res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256) 519 | } 520 | return res 521 | } 522 | 523 | Buffer.prototype.slice = function (start, end) { 524 | var len = this.length 525 | start = ~~start 526 | end = end === undefined ? len : ~~end 527 | 528 | if (start < 0) { 529 | start += len 530 | if (start < 0) 531 | start = 0 532 | } else if (start > len) { 533 | start = len 534 | } 535 | 536 | if (end < 0) { 537 | end += len 538 | if (end < 0) 539 | end = 0 540 | } else if (end > len) { 541 | end = len 542 | } 543 | 544 | if (end < start) 545 | end = start 546 | 547 | var newBuf 548 | if (Buffer.TYPED_ARRAY_SUPPORT) { 549 | newBuf = Buffer._augment(this.subarray(start, end)) 550 | } else { 551 | var sliceLen = end - start 552 | newBuf = new Buffer(sliceLen, undefined, true) 553 | for (var i = 0; i < sliceLen; i++) { 554 | newBuf[i] = this[i + start] 555 | } 556 | } 557 | 558 | if (newBuf.length) 559 | newBuf.parent = this.parent || this 560 | 561 | return newBuf 562 | } 563 | 564 | /* 565 | * Need to make sure that buffer isn't trying to write out of bounds. 566 | */ 567 | function checkOffset (offset, ext, length) { 568 | if ((offset % 1) !== 0 || offset < 0) 569 | throw new RangeError('offset is not uint') 570 | if (offset + ext > length) 571 | throw new RangeError('Trying to access beyond buffer length') 572 | } 573 | 574 | Buffer.prototype.readUIntLE = function (offset, byteLength, noAssert) { 575 | offset = offset >>> 0 576 | byteLength = byteLength >>> 0 577 | if (!noAssert) 578 | checkOffset(offset, byteLength, this.length) 579 | 580 | var val = this[offset] 581 | var mul = 1 582 | var i = 0 583 | while (++i < byteLength && (mul *= 0x100)) 584 | val += this[offset + i] * mul 585 | 586 | return val 587 | } 588 | 589 | Buffer.prototype.readUIntBE = function (offset, byteLength, noAssert) { 590 | offset = offset >>> 0 591 | byteLength = byteLength >>> 0 592 | if (!noAssert) 593 | checkOffset(offset, byteLength, this.length) 594 | 595 | var val = this[offset + --byteLength] 596 | var mul = 1 597 | while (byteLength > 0 && (mul *= 0x100)) 598 | val += this[offset + --byteLength] * mul 599 | 600 | return val 601 | } 602 | 603 | Buffer.prototype.readUInt8 = function (offset, noAssert) { 604 | if (!noAssert) 605 | checkOffset(offset, 1, this.length) 606 | return this[offset] 607 | } 608 | 609 | Buffer.prototype.readUInt16LE = function (offset, noAssert) { 610 | if (!noAssert) 611 | checkOffset(offset, 2, this.length) 612 | return this[offset] | (this[offset + 1] << 8) 613 | } 614 | 615 | Buffer.prototype.readUInt16BE = function (offset, noAssert) { 616 | if (!noAssert) 617 | checkOffset(offset, 2, this.length) 618 | return (this[offset] << 8) | this[offset + 1] 619 | } 620 | 621 | Buffer.prototype.readUInt32LE = function (offset, noAssert) { 622 | if (!noAssert) 623 | checkOffset(offset, 4, this.length) 624 | 625 | return ((this[offset]) | 626 | (this[offset + 1] << 8) | 627 | (this[offset + 2] << 16)) + 628 | (this[offset + 3] * 0x1000000) 629 | } 630 | 631 | Buffer.prototype.readUInt32BE = function (offset, noAssert) { 632 | if (!noAssert) 633 | checkOffset(offset, 4, this.length) 634 | 635 | return (this[offset] * 0x1000000) + 636 | ((this[offset + 1] << 16) | 637 | (this[offset + 2] << 8) | 638 | this[offset + 3]) 639 | } 640 | 641 | Buffer.prototype.readIntLE = function (offset, byteLength, noAssert) { 642 | offset = offset >>> 0 643 | byteLength = byteLength >>> 0 644 | if (!noAssert) 645 | checkOffset(offset, byteLength, this.length) 646 | 647 | var val = this[offset] 648 | var mul = 1 649 | var i = 0 650 | while (++i < byteLength && (mul *= 0x100)) 651 | val += this[offset + i] * mul 652 | mul *= 0x80 653 | 654 | if (val >= mul) 655 | val -= Math.pow(2, 8 * byteLength) 656 | 657 | return val 658 | } 659 | 660 | Buffer.prototype.readIntBE = function (offset, byteLength, noAssert) { 661 | offset = offset >>> 0 662 | byteLength = byteLength >>> 0 663 | if (!noAssert) 664 | checkOffset(offset, byteLength, this.length) 665 | 666 | var i = byteLength 667 | var mul = 1 668 | var val = this[offset + --i] 669 | while (i > 0 && (mul *= 0x100)) 670 | val += this[offset + --i] * mul 671 | mul *= 0x80 672 | 673 | if (val >= mul) 674 | val -= Math.pow(2, 8 * byteLength) 675 | 676 | return val 677 | } 678 | 679 | Buffer.prototype.readInt8 = function (offset, noAssert) { 680 | if (!noAssert) 681 | checkOffset(offset, 1, this.length) 682 | if (!(this[offset] & 0x80)) 683 | return (this[offset]) 684 | return ((0xff - this[offset] + 1) * -1) 685 | } 686 | 687 | Buffer.prototype.readInt16LE = function (offset, noAssert) { 688 | if (!noAssert) 689 | checkOffset(offset, 2, this.length) 690 | var val = this[offset] | (this[offset + 1] << 8) 691 | return (val & 0x8000) ? val | 0xFFFF0000 : val 692 | } 693 | 694 | Buffer.prototype.readInt16BE = function (offset, noAssert) { 695 | if (!noAssert) 696 | checkOffset(offset, 2, this.length) 697 | var val = this[offset + 1] | (this[offset] << 8) 698 | return (val & 0x8000) ? val | 0xFFFF0000 : val 699 | } 700 | 701 | Buffer.prototype.readInt32LE = function (offset, noAssert) { 702 | if (!noAssert) 703 | checkOffset(offset, 4, this.length) 704 | 705 | return (this[offset]) | 706 | (this[offset + 1] << 8) | 707 | (this[offset + 2] << 16) | 708 | (this[offset + 3] << 24) 709 | } 710 | 711 | Buffer.prototype.readInt32BE = function (offset, noAssert) { 712 | if (!noAssert) 713 | checkOffset(offset, 4, this.length) 714 | 715 | return (this[offset] << 24) | 716 | (this[offset + 1] << 16) | 717 | (this[offset + 2] << 8) | 718 | (this[offset + 3]) 719 | } 720 | 721 | Buffer.prototype.readFloatLE = function (offset, noAssert) { 722 | if (!noAssert) 723 | checkOffset(offset, 4, this.length) 724 | return ieee754.read(this, offset, true, 23, 4) 725 | } 726 | 727 | Buffer.prototype.readFloatBE = function (offset, noAssert) { 728 | if (!noAssert) 729 | checkOffset(offset, 4, this.length) 730 | return ieee754.read(this, offset, false, 23, 4) 731 | } 732 | 733 | Buffer.prototype.readDoubleLE = function (offset, noAssert) { 734 | if (!noAssert) 735 | checkOffset(offset, 8, this.length) 736 | return ieee754.read(this, offset, true, 52, 8) 737 | } 738 | 739 | Buffer.prototype.readDoubleBE = function (offset, noAssert) { 740 | if (!noAssert) 741 | checkOffset(offset, 8, this.length) 742 | return ieee754.read(this, offset, false, 52, 8) 743 | } 744 | 745 | function checkInt (buf, value, offset, ext, max, min) { 746 | if (!Buffer.isBuffer(buf)) throw new TypeError('buffer must be a Buffer instance') 747 | if (value > max || value < min) throw new RangeError('value is out of bounds') 748 | if (offset + ext > buf.length) throw new RangeError('index out of range') 749 | } 750 | 751 | Buffer.prototype.writeUIntLE = function (value, offset, byteLength, noAssert) { 752 | value = +value 753 | offset = offset >>> 0 754 | byteLength = byteLength >>> 0 755 | if (!noAssert) 756 | checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 757 | 758 | var mul = 1 759 | var i = 0 760 | this[offset] = value & 0xFF 761 | while (++i < byteLength && (mul *= 0x100)) 762 | this[offset + i] = (value / mul) >>> 0 & 0xFF 763 | 764 | return offset + byteLength 765 | } 766 | 767 | Buffer.prototype.writeUIntBE = function (value, offset, byteLength, noAssert) { 768 | value = +value 769 | offset = offset >>> 0 770 | byteLength = byteLength >>> 0 771 | if (!noAssert) 772 | checkInt(this, value, offset, byteLength, Math.pow(2, 8 * byteLength), 0) 773 | 774 | var i = byteLength - 1 775 | var mul = 1 776 | this[offset + i] = value & 0xFF 777 | while (--i >= 0 && (mul *= 0x100)) 778 | this[offset + i] = (value / mul) >>> 0 & 0xFF 779 | 780 | return offset + byteLength 781 | } 782 | 783 | Buffer.prototype.writeUInt8 = function (value, offset, noAssert) { 784 | value = +value 785 | offset = offset >>> 0 786 | if (!noAssert) 787 | checkInt(this, value, offset, 1, 0xff, 0) 788 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 789 | this[offset] = value 790 | return offset + 1 791 | } 792 | 793 | function objectWriteUInt16 (buf, value, offset, littleEndian) { 794 | if (value < 0) value = 0xffff + value + 1 795 | for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; i++) { 796 | buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>> 797 | (littleEndian ? i : 1 - i) * 8 798 | } 799 | } 800 | 801 | Buffer.prototype.writeUInt16LE = function (value, offset, noAssert) { 802 | value = +value 803 | offset = offset >>> 0 804 | if (!noAssert) 805 | checkInt(this, value, offset, 2, 0xffff, 0) 806 | if (Buffer.TYPED_ARRAY_SUPPORT) { 807 | this[offset] = value 808 | this[offset + 1] = (value >>> 8) 809 | } else objectWriteUInt16(this, value, offset, true) 810 | return offset + 2 811 | } 812 | 813 | Buffer.prototype.writeUInt16BE = function (value, offset, noAssert) { 814 | value = +value 815 | offset = offset >>> 0 816 | if (!noAssert) 817 | checkInt(this, value, offset, 2, 0xffff, 0) 818 | if (Buffer.TYPED_ARRAY_SUPPORT) { 819 | this[offset] = (value >>> 8) 820 | this[offset + 1] = value 821 | } else objectWriteUInt16(this, value, offset, false) 822 | return offset + 2 823 | } 824 | 825 | function objectWriteUInt32 (buf, value, offset, littleEndian) { 826 | if (value < 0) value = 0xffffffff + value + 1 827 | for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; i++) { 828 | buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff 829 | } 830 | } 831 | 832 | Buffer.prototype.writeUInt32LE = function (value, offset, noAssert) { 833 | value = +value 834 | offset = offset >>> 0 835 | if (!noAssert) 836 | checkInt(this, value, offset, 4, 0xffffffff, 0) 837 | if (Buffer.TYPED_ARRAY_SUPPORT) { 838 | this[offset + 3] = (value >>> 24) 839 | this[offset + 2] = (value >>> 16) 840 | this[offset + 1] = (value >>> 8) 841 | this[offset] = value 842 | } else objectWriteUInt32(this, value, offset, true) 843 | return offset + 4 844 | } 845 | 846 | Buffer.prototype.writeUInt32BE = function (value, offset, noAssert) { 847 | value = +value 848 | offset = offset >>> 0 849 | if (!noAssert) 850 | checkInt(this, value, offset, 4, 0xffffffff, 0) 851 | if (Buffer.TYPED_ARRAY_SUPPORT) { 852 | this[offset] = (value >>> 24) 853 | this[offset + 1] = (value >>> 16) 854 | this[offset + 2] = (value >>> 8) 855 | this[offset + 3] = value 856 | } else objectWriteUInt32(this, value, offset, false) 857 | return offset + 4 858 | } 859 | 860 | Buffer.prototype.writeIntLE = function (value, offset, byteLength, noAssert) { 861 | value = +value 862 | offset = offset >>> 0 863 | if (!noAssert) { 864 | checkInt(this, 865 | value, 866 | offset, 867 | byteLength, 868 | Math.pow(2, 8 * byteLength - 1) - 1, 869 | -Math.pow(2, 8 * byteLength - 1)) 870 | } 871 | 872 | var i = 0 873 | var mul = 1 874 | var sub = value < 0 ? 1 : 0 875 | this[offset] = value & 0xFF 876 | while (++i < byteLength && (mul *= 0x100)) 877 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 878 | 879 | return offset + byteLength 880 | } 881 | 882 | Buffer.prototype.writeIntBE = function (value, offset, byteLength, noAssert) { 883 | value = +value 884 | offset = offset >>> 0 885 | if (!noAssert) { 886 | checkInt(this, 887 | value, 888 | offset, 889 | byteLength, 890 | Math.pow(2, 8 * byteLength - 1) - 1, 891 | -Math.pow(2, 8 * byteLength - 1)) 892 | } 893 | 894 | var i = byteLength - 1 895 | var mul = 1 896 | var sub = value < 0 ? 1 : 0 897 | this[offset + i] = value & 0xFF 898 | while (--i >= 0 && (mul *= 0x100)) 899 | this[offset + i] = ((value / mul) >> 0) - sub & 0xFF 900 | 901 | return offset + byteLength 902 | } 903 | 904 | Buffer.prototype.writeInt8 = function (value, offset, noAssert) { 905 | value = +value 906 | offset = offset >>> 0 907 | if (!noAssert) 908 | checkInt(this, value, offset, 1, 0x7f, -0x80) 909 | if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value) 910 | if (value < 0) value = 0xff + value + 1 911 | this[offset] = value 912 | return offset + 1 913 | } 914 | 915 | Buffer.prototype.writeInt16LE = function (value, offset, noAssert) { 916 | value = +value 917 | offset = offset >>> 0 918 | if (!noAssert) 919 | checkInt(this, value, offset, 2, 0x7fff, -0x8000) 920 | if (Buffer.TYPED_ARRAY_SUPPORT) { 921 | this[offset] = value 922 | this[offset + 1] = (value >>> 8) 923 | } else objectWriteUInt16(this, value, offset, true) 924 | return offset + 2 925 | } 926 | 927 | Buffer.prototype.writeInt16BE = function (value, offset, noAssert) { 928 | value = +value 929 | offset = offset >>> 0 930 | if (!noAssert) 931 | checkInt(this, value, offset, 2, 0x7fff, -0x8000) 932 | if (Buffer.TYPED_ARRAY_SUPPORT) { 933 | this[offset] = (value >>> 8) 934 | this[offset + 1] = value 935 | } else objectWriteUInt16(this, value, offset, false) 936 | return offset + 2 937 | } 938 | 939 | Buffer.prototype.writeInt32LE = function (value, offset, noAssert) { 940 | value = +value 941 | offset = offset >>> 0 942 | if (!noAssert) 943 | checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 944 | if (Buffer.TYPED_ARRAY_SUPPORT) { 945 | this[offset] = value 946 | this[offset + 1] = (value >>> 8) 947 | this[offset + 2] = (value >>> 16) 948 | this[offset + 3] = (value >>> 24) 949 | } else objectWriteUInt32(this, value, offset, true) 950 | return offset + 4 951 | } 952 | 953 | Buffer.prototype.writeInt32BE = function (value, offset, noAssert) { 954 | value = +value 955 | offset = offset >>> 0 956 | if (!noAssert) 957 | checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000) 958 | if (value < 0) value = 0xffffffff + value + 1 959 | if (Buffer.TYPED_ARRAY_SUPPORT) { 960 | this[offset] = (value >>> 24) 961 | this[offset + 1] = (value >>> 16) 962 | this[offset + 2] = (value >>> 8) 963 | this[offset + 3] = value 964 | } else objectWriteUInt32(this, value, offset, false) 965 | return offset + 4 966 | } 967 | 968 | function checkIEEE754 (buf, value, offset, ext, max, min) { 969 | if (value > max || value < min) throw new RangeError('value is out of bounds') 970 | if (offset + ext > buf.length) throw new RangeError('index out of range') 971 | if (offset < 0) throw new RangeError('index out of range') 972 | } 973 | 974 | function writeFloat (buf, value, offset, littleEndian, noAssert) { 975 | if (!noAssert) 976 | checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38) 977 | ieee754.write(buf, value, offset, littleEndian, 23, 4) 978 | return offset + 4 979 | } 980 | 981 | Buffer.prototype.writeFloatLE = function (value, offset, noAssert) { 982 | return writeFloat(this, value, offset, true, noAssert) 983 | } 984 | 985 | Buffer.prototype.writeFloatBE = function (value, offset, noAssert) { 986 | return writeFloat(this, value, offset, false, noAssert) 987 | } 988 | 989 | function writeDouble (buf, value, offset, littleEndian, noAssert) { 990 | if (!noAssert) 991 | checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308) 992 | ieee754.write(buf, value, offset, littleEndian, 52, 8) 993 | return offset + 8 994 | } 995 | 996 | Buffer.prototype.writeDoubleLE = function (value, offset, noAssert) { 997 | return writeDouble(this, value, offset, true, noAssert) 998 | } 999 | 1000 | Buffer.prototype.writeDoubleBE = function (value, offset, noAssert) { 1001 | return writeDouble(this, value, offset, false, noAssert) 1002 | } 1003 | 1004 | // copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length) 1005 | Buffer.prototype.copy = function (target, target_start, start, end) { 1006 | var self = this // source 1007 | 1008 | if (!start) start = 0 1009 | if (!end && end !== 0) end = this.length 1010 | if (target_start >= target.length) target_start = target.length 1011 | if (!target_start) target_start = 0 1012 | if (end > 0 && end < start) end = start 1013 | 1014 | // Copy 0 bytes; we're done 1015 | if (end === start) return 0 1016 | if (target.length === 0 || self.length === 0) return 0 1017 | 1018 | // Fatal error conditions 1019 | if (target_start < 0) 1020 | throw new RangeError('targetStart out of bounds') 1021 | if (start < 0 || start >= self.length) throw new RangeError('sourceStart out of bounds') 1022 | if (end < 0) throw new RangeError('sourceEnd out of bounds') 1023 | 1024 | // Are we oob? 1025 | if (end > this.length) 1026 | end = this.length 1027 | if (target.length - target_start < end - start) 1028 | end = target.length - target_start + start 1029 | 1030 | var len = end - start 1031 | 1032 | if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) { 1033 | for (var i = 0; i < len; i++) { 1034 | target[i + target_start] = this[i + start] 1035 | } 1036 | } else { 1037 | target._set(this.subarray(start, start + len), target_start) 1038 | } 1039 | 1040 | return len 1041 | } 1042 | 1043 | // fill(value, start=0, end=buffer.length) 1044 | Buffer.prototype.fill = function (value, start, end) { 1045 | if (!value) value = 0 1046 | if (!start) start = 0 1047 | if (!end) end = this.length 1048 | 1049 | if (end < start) throw new RangeError('end < start') 1050 | 1051 | // Fill 0 bytes; we're done 1052 | if (end === start) return 1053 | if (this.length === 0) return 1054 | 1055 | if (start < 0 || start >= this.length) throw new RangeError('start out of bounds') 1056 | if (end < 0 || end > this.length) throw new RangeError('end out of bounds') 1057 | 1058 | var i 1059 | if (typeof value === 'number') { 1060 | for (i = start; i < end; i++) { 1061 | this[i] = value 1062 | } 1063 | } else { 1064 | var bytes = utf8ToBytes(value.toString()) 1065 | var len = bytes.length 1066 | for (i = start; i < end; i++) { 1067 | this[i] = bytes[i % len] 1068 | } 1069 | } 1070 | 1071 | return this 1072 | } 1073 | 1074 | /** 1075 | * Creates a new `ArrayBuffer` with the *copied* memory of the buffer instance. 1076 | * Added in Node 0.12. Only available in browsers that support ArrayBuffer. 1077 | */ 1078 | Buffer.prototype.toArrayBuffer = function () { 1079 | if (typeof Uint8Array !== 'undefined') { 1080 | if (Buffer.TYPED_ARRAY_SUPPORT) { 1081 | return (new Buffer(this)).buffer 1082 | } else { 1083 | var buf = new Uint8Array(this.length) 1084 | for (var i = 0, len = buf.length; i < len; i += 1) { 1085 | buf[i] = this[i] 1086 | } 1087 | return buf.buffer 1088 | } 1089 | } else { 1090 | throw new TypeError('Buffer.toArrayBuffer not supported in this browser') 1091 | } 1092 | } 1093 | 1094 | // HELPER FUNCTIONS 1095 | // ================ 1096 | 1097 | var BP = Buffer.prototype 1098 | 1099 | /** 1100 | * Augment a Uint8Array *instance* (not the Uint8Array class!) with Buffer methods 1101 | */ 1102 | Buffer._augment = function (arr) { 1103 | arr.constructor = Buffer 1104 | arr._isBuffer = true 1105 | 1106 | // save reference to original Uint8Array get/set methods before overwriting 1107 | arr._get = arr.get 1108 | arr._set = arr.set 1109 | 1110 | // deprecated, will be removed in node 0.13+ 1111 | arr.get = BP.get 1112 | arr.set = BP.set 1113 | 1114 | arr.write = BP.write 1115 | arr.toString = BP.toString 1116 | arr.toLocaleString = BP.toString 1117 | arr.toJSON = BP.toJSON 1118 | arr.equals = BP.equals 1119 | arr.compare = BP.compare 1120 | arr.copy = BP.copy 1121 | arr.slice = BP.slice 1122 | arr.readUIntLE = BP.readUIntLE 1123 | arr.readUIntBE = BP.readUIntBE 1124 | arr.readUInt8 = BP.readUInt8 1125 | arr.readUInt16LE = BP.readUInt16LE 1126 | arr.readUInt16BE = BP.readUInt16BE 1127 | arr.readUInt32LE = BP.readUInt32LE 1128 | arr.readUInt32BE = BP.readUInt32BE 1129 | arr.readIntLE = BP.readIntLE 1130 | arr.readIntBE = BP.readIntBE 1131 | arr.readInt8 = BP.readInt8 1132 | arr.readInt16LE = BP.readInt16LE 1133 | arr.readInt16BE = BP.readInt16BE 1134 | arr.readInt32LE = BP.readInt32LE 1135 | arr.readInt32BE = BP.readInt32BE 1136 | arr.readFloatLE = BP.readFloatLE 1137 | arr.readFloatBE = BP.readFloatBE 1138 | arr.readDoubleLE = BP.readDoubleLE 1139 | arr.readDoubleBE = BP.readDoubleBE 1140 | arr.writeUInt8 = BP.writeUInt8 1141 | arr.writeUIntLE = BP.writeUIntLE 1142 | arr.writeUIntBE = BP.writeUIntBE 1143 | arr.writeUInt16LE = BP.writeUInt16LE 1144 | arr.writeUInt16BE = BP.writeUInt16BE 1145 | arr.writeUInt32LE = BP.writeUInt32LE 1146 | arr.writeUInt32BE = BP.writeUInt32BE 1147 | arr.writeIntLE = BP.writeIntLE 1148 | arr.writeIntBE = BP.writeIntBE 1149 | arr.writeInt8 = BP.writeInt8 1150 | arr.writeInt16LE = BP.writeInt16LE 1151 | arr.writeInt16BE = BP.writeInt16BE 1152 | arr.writeInt32LE = BP.writeInt32LE 1153 | arr.writeInt32BE = BP.writeInt32BE 1154 | arr.writeFloatLE = BP.writeFloatLE 1155 | arr.writeFloatBE = BP.writeFloatBE 1156 | arr.writeDoubleLE = BP.writeDoubleLE 1157 | arr.writeDoubleBE = BP.writeDoubleBE 1158 | arr.fill = BP.fill 1159 | arr.inspect = BP.inspect 1160 | arr.toArrayBuffer = BP.toArrayBuffer 1161 | 1162 | return arr 1163 | } 1164 | 1165 | var INVALID_BASE64_RE = /[^+\/0-9A-z\-]/g 1166 | 1167 | function base64clean (str) { 1168 | // Node strips out invalid characters like \n and \t from the string, base64-js does not 1169 | str = stringtrim(str).replace(INVALID_BASE64_RE, '') 1170 | // Node converts strings with length < 2 to '' 1171 | if (str.length < 2) return '' 1172 | // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not 1173 | while (str.length % 4 !== 0) { 1174 | str = str + '=' 1175 | } 1176 | return str 1177 | } 1178 | 1179 | function stringtrim (str) { 1180 | if (str.trim) return str.trim() 1181 | return str.replace(/^\s+|\s+$/g, '') 1182 | } 1183 | 1184 | function isArrayish (subject) { 1185 | return isArray(subject) || Buffer.isBuffer(subject) || 1186 | subject && typeof subject === 'object' && 1187 | typeof subject.length === 'number' 1188 | } 1189 | 1190 | function toHex (n) { 1191 | if (n < 16) return '0' + n.toString(16) 1192 | return n.toString(16) 1193 | } 1194 | 1195 | function utf8ToBytes (string, units) { 1196 | units = units || Infinity 1197 | var codePoint 1198 | var length = string.length 1199 | var leadSurrogate = null 1200 | var bytes = [] 1201 | var i = 0 1202 | 1203 | for (; i < length; i++) { 1204 | codePoint = string.charCodeAt(i) 1205 | 1206 | // is surrogate component 1207 | if (codePoint > 0xD7FF && codePoint < 0xE000) { 1208 | // last char was a lead 1209 | if (leadSurrogate) { 1210 | // 2 leads in a row 1211 | if (codePoint < 0xDC00) { 1212 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 1213 | leadSurrogate = codePoint 1214 | continue 1215 | } else { 1216 | // valid surrogate pair 1217 | codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000 1218 | leadSurrogate = null 1219 | } 1220 | } else { 1221 | // no lead yet 1222 | 1223 | if (codePoint > 0xDBFF) { 1224 | // unexpected trail 1225 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 1226 | continue 1227 | } else if (i + 1 === length) { 1228 | // unpaired lead 1229 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 1230 | continue 1231 | } else { 1232 | // valid lead 1233 | leadSurrogate = codePoint 1234 | continue 1235 | } 1236 | } 1237 | } else if (leadSurrogate) { 1238 | // valid bmp char, but last char was a lead 1239 | if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD) 1240 | leadSurrogate = null 1241 | } 1242 | 1243 | // encode utf8 1244 | if (codePoint < 0x80) { 1245 | if ((units -= 1) < 0) break 1246 | bytes.push(codePoint) 1247 | } else if (codePoint < 0x800) { 1248 | if ((units -= 2) < 0) break 1249 | bytes.push( 1250 | codePoint >> 0x6 | 0xC0, 1251 | codePoint & 0x3F | 0x80 1252 | ) 1253 | } else if (codePoint < 0x10000) { 1254 | if ((units -= 3) < 0) break 1255 | bytes.push( 1256 | codePoint >> 0xC | 0xE0, 1257 | codePoint >> 0x6 & 0x3F | 0x80, 1258 | codePoint & 0x3F | 0x80 1259 | ) 1260 | } else if (codePoint < 0x200000) { 1261 | if ((units -= 4) < 0) break 1262 | bytes.push( 1263 | codePoint >> 0x12 | 0xF0, 1264 | codePoint >> 0xC & 0x3F | 0x80, 1265 | codePoint >> 0x6 & 0x3F | 0x80, 1266 | codePoint & 0x3F | 0x80 1267 | ) 1268 | } else { 1269 | throw new Error('Invalid code point') 1270 | } 1271 | } 1272 | 1273 | return bytes 1274 | } 1275 | 1276 | function asciiToBytes (str) { 1277 | var byteArray = [] 1278 | for (var i = 0; i < str.length; i++) { 1279 | // Node's code seems to be doing this and not & 0x7F.. 1280 | byteArray.push(str.charCodeAt(i) & 0xFF) 1281 | } 1282 | return byteArray 1283 | } 1284 | 1285 | function utf16leToBytes (str, units) { 1286 | var c, hi, lo 1287 | var byteArray = [] 1288 | for (var i = 0; i < str.length; i++) { 1289 | if ((units -= 2) < 0) break 1290 | 1291 | c = str.charCodeAt(i) 1292 | hi = c >> 8 1293 | lo = c % 256 1294 | byteArray.push(lo) 1295 | byteArray.push(hi) 1296 | } 1297 | 1298 | return byteArray 1299 | } 1300 | 1301 | function base64ToBytes (str) { 1302 | return base64.toByteArray(base64clean(str)) 1303 | } 1304 | 1305 | function blitBuffer (src, dst, offset, length) { 1306 | for (var i = 0; i < length; i++) { 1307 | if ((i + offset >= dst.length) || (i >= src.length)) 1308 | break 1309 | dst[i + offset] = src[i] 1310 | } 1311 | return i 1312 | } 1313 | 1314 | function decodeUtf8Char (str) { 1315 | try { 1316 | return decodeURIComponent(str) 1317 | } catch (err) { 1318 | return String.fromCharCode(0xFFFD) // UTF 8 invalid char 1319 | } 1320 | } 1321 | 1322 | },{"base64-js":3,"ieee754":4,"is-array":5}],3:[function(require,module,exports){ 1323 | var lookup = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; 1324 | 1325 | ;(function (exports) { 1326 | 'use strict'; 1327 | 1328 | var Arr = (typeof Uint8Array !== 'undefined') 1329 | ? Uint8Array 1330 | : Array 1331 | 1332 | var PLUS = '+'.charCodeAt(0) 1333 | var SLASH = '/'.charCodeAt(0) 1334 | var NUMBER = '0'.charCodeAt(0) 1335 | var LOWER = 'a'.charCodeAt(0) 1336 | var UPPER = 'A'.charCodeAt(0) 1337 | var PLUS_URL_SAFE = '-'.charCodeAt(0) 1338 | var SLASH_URL_SAFE = '_'.charCodeAt(0) 1339 | 1340 | function decode (elt) { 1341 | var code = elt.charCodeAt(0) 1342 | if (code === PLUS || 1343 | code === PLUS_URL_SAFE) 1344 | return 62 // '+' 1345 | if (code === SLASH || 1346 | code === SLASH_URL_SAFE) 1347 | return 63 // '/' 1348 | if (code < NUMBER) 1349 | return -1 //no match 1350 | if (code < NUMBER + 10) 1351 | return code - NUMBER + 26 + 26 1352 | if (code < UPPER + 26) 1353 | return code - UPPER 1354 | if (code < LOWER + 26) 1355 | return code - LOWER + 26 1356 | } 1357 | 1358 | function b64ToByteArray (b64) { 1359 | var i, j, l, tmp, placeHolders, arr 1360 | 1361 | if (b64.length % 4 > 0) { 1362 | throw new Error('Invalid string. Length must be a multiple of 4') 1363 | } 1364 | 1365 | // the number of equal signs (place holders) 1366 | // if there are two placeholders, than the two characters before it 1367 | // represent one byte 1368 | // if there is only one, then the three characters before it represent 2 bytes 1369 | // this is just a cheap hack to not do indexOf twice 1370 | var len = b64.length 1371 | placeHolders = '=' === b64.charAt(len - 2) ? 2 : '=' === b64.charAt(len - 1) ? 1 : 0 1372 | 1373 | // base64 is 4/3 + up to two characters of the original data 1374 | arr = new Arr(b64.length * 3 / 4 - placeHolders) 1375 | 1376 | // if there are placeholders, only get up to the last complete 4 chars 1377 | l = placeHolders > 0 ? b64.length - 4 : b64.length 1378 | 1379 | var L = 0 1380 | 1381 | function push (v) { 1382 | arr[L++] = v 1383 | } 1384 | 1385 | for (i = 0, j = 0; i < l; i += 4, j += 3) { 1386 | tmp = (decode(b64.charAt(i)) << 18) | (decode(b64.charAt(i + 1)) << 12) | (decode(b64.charAt(i + 2)) << 6) | decode(b64.charAt(i + 3)) 1387 | push((tmp & 0xFF0000) >> 16) 1388 | push((tmp & 0xFF00) >> 8) 1389 | push(tmp & 0xFF) 1390 | } 1391 | 1392 | if (placeHolders === 2) { 1393 | tmp = (decode(b64.charAt(i)) << 2) | (decode(b64.charAt(i + 1)) >> 4) 1394 | push(tmp & 0xFF) 1395 | } else if (placeHolders === 1) { 1396 | tmp = (decode(b64.charAt(i)) << 10) | (decode(b64.charAt(i + 1)) << 4) | (decode(b64.charAt(i + 2)) >> 2) 1397 | push((tmp >> 8) & 0xFF) 1398 | push(tmp & 0xFF) 1399 | } 1400 | 1401 | return arr 1402 | } 1403 | 1404 | function uint8ToBase64 (uint8) { 1405 | var i, 1406 | extraBytes = uint8.length % 3, // if we have 1 byte left, pad 2 bytes 1407 | output = "", 1408 | temp, length 1409 | 1410 | function encode (num) { 1411 | return lookup.charAt(num) 1412 | } 1413 | 1414 | function tripletToBase64 (num) { 1415 | return encode(num >> 18 & 0x3F) + encode(num >> 12 & 0x3F) + encode(num >> 6 & 0x3F) + encode(num & 0x3F) 1416 | } 1417 | 1418 | // go through the array every three bytes, we'll deal with trailing stuff later 1419 | for (i = 0, length = uint8.length - extraBytes; i < length; i += 3) { 1420 | temp = (uint8[i] << 16) + (uint8[i + 1] << 8) + (uint8[i + 2]) 1421 | output += tripletToBase64(temp) 1422 | } 1423 | 1424 | // pad the end with zeros, but make sure to not forget the extra bytes 1425 | switch (extraBytes) { 1426 | case 1: 1427 | temp = uint8[uint8.length - 1] 1428 | output += encode(temp >> 2) 1429 | output += encode((temp << 4) & 0x3F) 1430 | output += '==' 1431 | break 1432 | case 2: 1433 | temp = (uint8[uint8.length - 2] << 8) + (uint8[uint8.length - 1]) 1434 | output += encode(temp >> 10) 1435 | output += encode((temp >> 4) & 0x3F) 1436 | output += encode((temp << 2) & 0x3F) 1437 | output += '=' 1438 | break 1439 | } 1440 | 1441 | return output 1442 | } 1443 | 1444 | exports.toByteArray = b64ToByteArray 1445 | exports.fromByteArray = uint8ToBase64 1446 | }(typeof exports === 'undefined' ? (this.base64js = {}) : exports)) 1447 | 1448 | },{}],4:[function(require,module,exports){ 1449 | exports.read = function(buffer, offset, isLE, mLen, nBytes) { 1450 | var e, m, 1451 | eLen = nBytes * 8 - mLen - 1, 1452 | eMax = (1 << eLen) - 1, 1453 | eBias = eMax >> 1, 1454 | nBits = -7, 1455 | i = isLE ? (nBytes - 1) : 0, 1456 | d = isLE ? -1 : 1, 1457 | s = buffer[offset + i]; 1458 | 1459 | i += d; 1460 | 1461 | e = s & ((1 << (-nBits)) - 1); 1462 | s >>= (-nBits); 1463 | nBits += eLen; 1464 | for (; nBits > 0; e = e * 256 + buffer[offset + i], i += d, nBits -= 8); 1465 | 1466 | m = e & ((1 << (-nBits)) - 1); 1467 | e >>= (-nBits); 1468 | nBits += mLen; 1469 | for (; nBits > 0; m = m * 256 + buffer[offset + i], i += d, nBits -= 8); 1470 | 1471 | if (e === 0) { 1472 | e = 1 - eBias; 1473 | } else if (e === eMax) { 1474 | return m ? NaN : ((s ? -1 : 1) * Infinity); 1475 | } else { 1476 | m = m + Math.pow(2, mLen); 1477 | e = e - eBias; 1478 | } 1479 | return (s ? -1 : 1) * m * Math.pow(2, e - mLen); 1480 | }; 1481 | 1482 | exports.write = function(buffer, value, offset, isLE, mLen, nBytes) { 1483 | var e, m, c, 1484 | eLen = nBytes * 8 - mLen - 1, 1485 | eMax = (1 << eLen) - 1, 1486 | eBias = eMax >> 1, 1487 | rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0), 1488 | i = isLE ? 0 : (nBytes - 1), 1489 | d = isLE ? 1 : -1, 1490 | s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0; 1491 | 1492 | value = Math.abs(value); 1493 | 1494 | if (isNaN(value) || value === Infinity) { 1495 | m = isNaN(value) ? 1 : 0; 1496 | e = eMax; 1497 | } else { 1498 | e = Math.floor(Math.log(value) / Math.LN2); 1499 | if (value * (c = Math.pow(2, -e)) < 1) { 1500 | e--; 1501 | c *= 2; 1502 | } 1503 | if (e + eBias >= 1) { 1504 | value += rt / c; 1505 | } else { 1506 | value += rt * Math.pow(2, 1 - eBias); 1507 | } 1508 | if (value * c >= 2) { 1509 | e++; 1510 | c /= 2; 1511 | } 1512 | 1513 | if (e + eBias >= eMax) { 1514 | m = 0; 1515 | e = eMax; 1516 | } else if (e + eBias >= 1) { 1517 | m = (value * c - 1) * Math.pow(2, mLen); 1518 | e = e + eBias; 1519 | } else { 1520 | m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen); 1521 | e = 0; 1522 | } 1523 | } 1524 | 1525 | for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8); 1526 | 1527 | e = (e << mLen) | m; 1528 | eLen += mLen; 1529 | for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8); 1530 | 1531 | buffer[offset + i - d] |= s * 128; 1532 | }; 1533 | 1534 | },{}],5:[function(require,module,exports){ 1535 | 1536 | /** 1537 | * isArray 1538 | */ 1539 | 1540 | var isArray = Array.isArray; 1541 | 1542 | /** 1543 | * toString 1544 | */ 1545 | 1546 | var str = Object.prototype.toString; 1547 | 1548 | /** 1549 | * Whether or not the given `val` 1550 | * is an array. 1551 | * 1552 | * example: 1553 | * 1554 | * isArray([]); 1555 | * // > true 1556 | * isArray(arguments); 1557 | * // > false 1558 | * isArray(''); 1559 | * // > false 1560 | * 1561 | * @param {mixed} val 1562 | * @return {bool} 1563 | */ 1564 | 1565 | module.exports = isArray || function (val) { 1566 | return !! val && '[object Array]' == str.call(val); 1567 | }; 1568 | 1569 | },{}]},{},[1]); 1570 | -------------------------------------------------------------------------------- /test/enumTest.js: -------------------------------------------------------------------------------- 1 | (function(global){ 2 | var expect = global.expect || require('expect.js'); 3 | var endianness = global.Enum ? 'LE' : require('os').endianness(); 4 | var e = global.Enum || require('../'); 5 | 6 | // for zuul / saucelabs 7 | Enum = undefined; 8 | 9 | function envSupportsFreezing() { 10 | return ( 11 | Object.isFrozen && Object.isSealed && 12 | Object.getOwnPropertyNames && Object.getOwnPropertyDescriptor && 13 | Object.defineProperties && Object.__defineGetter__ && Object.__defineSetter__ 14 | ); 15 | } 16 | 17 | describe('Enum', function() { 18 | 19 | describe('calling register', function() { 20 | 21 | it('it should register Enum on global namespace', function() { 22 | 23 | expect(Enum).not.to.be.ok(); 24 | e.register(); 25 | expect(Enum).to.be.ok(); 26 | 27 | }); 28 | 29 | }); 30 | 31 | describe('defining an enum', function() { 32 | 33 | var myEnum; 34 | 35 | describe('in a simple or complex way', function() { 36 | 37 | it('it should be the same', function() { 38 | 39 | myEnum = new e(['A', 'B', 'C']); 40 | 41 | var myEnum2 = new e({'A': 1, 'B': 2, 'C': 4}); 42 | 43 | expect(myEnum.A).to.eql(myEnum2.A); 44 | expect(myEnum.C).to.eql(myEnum2.C); 45 | 46 | expect(myEnum.A.value).to.eql(myEnum2.A.value); 47 | expect(myEnum.C.value).to.eql(myEnum2.C.value); 48 | 49 | }); 50 | 51 | describe('calling toJSON', function () { 52 | 53 | it('it should return a copy of the whole enum type', function() { 54 | 55 | var json = myEnum.toJSON(); 56 | expect(json).to.have.property('A', 1); 57 | expect(json).to.have.property('B', 2); 58 | expect(json).to.have.property('C', 4); 59 | 60 | }); 61 | 62 | }); 63 | 64 | describe('stringifying', function () { 65 | 66 | it('it should return a copy of the whole enum type', function() { 67 | 68 | expect(JSON.stringify(myEnum)).to.be('{"A":1,"B":2,"C":4}'); 69 | 70 | }); 71 | 72 | }); 73 | 74 | describe('it should be possible to', function() { 75 | 76 | it('get an enum item', function() { 77 | 78 | expect(myEnum.A).to.have.property('value', 1); 79 | expect(myEnum.A).to.have.property('key', 'A'); 80 | 81 | expect(myEnum.C).to.have.property('value', 4); 82 | expect(myEnum.C).to.have.property('key', 'C'); 83 | 84 | }); 85 | 86 | it('get all enum values', function() { 87 | 88 | expect(myEnum.enums).to.be.an('array'); 89 | expect(myEnum.enums).to.have.length(3); 90 | expect(myEnum.enums).to.contain(myEnum.A); 91 | expect(myEnum.enums).to.contain(myEnum.B); 92 | expect(myEnum.enums).to.contain(myEnum.C); 93 | 94 | }); 95 | 96 | describe('call has', function() { 97 | 98 | describe('on a flagged enum item', function() { 99 | 100 | var myItem; 101 | 102 | before(function() { 103 | myItem = myEnum.get(3); 104 | expect(myEnum.get('A | B').value).to.eql(myItem.value); 105 | }); 106 | 107 | it('with another item', function() { 108 | 109 | expect(myItem.has(myEnum.B)).to.be(true); 110 | expect(myItem.has(myEnum.C)).not.to.be(true); 111 | 112 | }); 113 | 114 | it('with another key', function() { 115 | 116 | expect(myItem.has('B')).to.be(true); 117 | expect(myItem.has('C')).not.to.be(true); 118 | 119 | }); 120 | 121 | it('with another value', function() { 122 | 123 | expect(myItem.has(2)).to.be(true); 124 | expect(myItem.has(4)).not.to.be(true); 125 | 126 | }); 127 | 128 | }); 129 | 130 | }); 131 | 132 | describe('compare', function() { 133 | 134 | describe('an item', function() { 135 | 136 | it('has been defined', function() { 137 | 138 | expect(myEnum.isDefined(myEnum.A)).to.be(true); 139 | expect(myEnum.isDefined('A')).to.be(true); 140 | expect(myEnum.isDefined(1)).to.be(true); 141 | 142 | var myEnum2 = new e({'A': 1, 'B': 2, 'C': 4}); 143 | expect(myEnum2.isDefined(myEnum2.C)).to.be(true); 144 | expect(myEnum2.isDefined('C')).to.be(true); 145 | expect(myEnum2.isDefined(4)).to.be(true); 146 | 147 | expect(myEnum.isDefined(myEnum2.C)).to.be(false); 148 | expect(myEnum2.isDefined(myEnum.A)).to.be(false); 149 | 150 | expect(myEnum.isDefined(myEnum)).to.be(false); 151 | expect(myEnum.isDefined(myEnum2)).to.be(false); 152 | 153 | expect(myEnum.isDefined()).to.be(false); 154 | expect(myEnum.isDefined('Z')).to.be(false); 155 | expect(myEnum.isDefined(10)).to.be(false); 156 | expect(myEnum.isDefined({})).to.be(false); 157 | expect(myEnum.isDefined(null)).to.be(false); 158 | expect(myEnum.isDefined(undefined)).to.be(false); 159 | 160 | }); 161 | 162 | }); 163 | 164 | describe('an item and an item', function() { 165 | 166 | it('with is', function() { 167 | 168 | expect(myEnum.A.is(myEnum.A)).to.be(true); 169 | expect(myEnum.A.is(myEnum.C)).not.to.be(true); 170 | 171 | }); 172 | 173 | it('with has', function() { 174 | 175 | expect(myEnum.A.has(myEnum.A)).to.be(true); 176 | expect(myEnum.A.has(myEnum.C)).not.to.be(true); 177 | 178 | }); 179 | 180 | it('with ==', function() { 181 | 182 | expect(myEnum.A == myEnum.A).to.be(true); 183 | expect(myEnum.A == myEnum.C).not.to.be(true); 184 | 185 | }); 186 | 187 | it('with ===', function() { 188 | 189 | expect(myEnum.A === myEnum.A).to.be(true); 190 | expect(myEnum.A === myEnum.C).not.to.be(true); 191 | 192 | }); 193 | 194 | }); 195 | 196 | describe('an item and a key', function() { 197 | 198 | it('with is', function() { 199 | 200 | expect(myEnum.A.is('A')).to.be(true); 201 | expect(myEnum.A.is('C')).not.to.be(true); 202 | 203 | }); 204 | 205 | it('with has', function() { 206 | 207 | expect(myEnum.A.has('A')).to.be(true); 208 | expect(myEnum.A.has('C')).not.to.be(true); 209 | 210 | }); 211 | 212 | it('with ==', function() { 213 | 214 | expect(myEnum.A == myEnum.A.value).to.be(true); 215 | expect(myEnum.A == myEnum.C.value).not.to.be(true); 216 | 217 | }); 218 | 219 | }); 220 | 221 | describe('an item and a value', function() { 222 | 223 | it('with is', function() { 224 | 225 | expect(myEnum.A.is(1)).to.be(true); 226 | expect(myEnum.A.is(4)).not.to.be(true); 227 | 228 | }); 229 | 230 | it('with has', function() { 231 | 232 | expect(myEnum.A.has(1)).to.be(true); 233 | expect(myEnum.A.has(4)).not.to.be(true); 234 | 235 | }); 236 | 237 | }); 238 | 239 | }); 240 | 241 | describe('call get and get', function() { 242 | 243 | it('an enum item by item', function() { 244 | 245 | expect(myEnum.get(myEnum.A)).to.have.property('value', 1); 246 | expect(myEnum.get(myEnum.A)).to.have.property('key', 'A'); 247 | 248 | expect(myEnum.get(myEnum.C)).to.have.property('value', 4); 249 | expect(myEnum.get(myEnum.C)).to.have.property('key', 'C'); 250 | 251 | }); 252 | 253 | it('an enum item by flagged item', function() { 254 | 255 | var item = myEnum.get('A | B'); 256 | 257 | expect(myEnum.get(item)).to.have.property('value', 3); 258 | expect(myEnum.get(item)).to.have.property('key', 'A | B'); 259 | 260 | }); 261 | 262 | it('an enum item by value', function() { 263 | 264 | expect(myEnum.get('A')).to.have.property('value', 1); 265 | expect(myEnum.get('A')).to.have.property('key', 'A'); 266 | 267 | expect(myEnum.get('C')).to.have.property('value', 4); 268 | expect(myEnum.get('C')).to.have.property('key', 'C'); 269 | 270 | }); 271 | 272 | it('an enum item by key', function() { 273 | 274 | expect(myEnum.get(1)).to.have.property('value', 1); 275 | expect(myEnum.get(1)).to.have.property('key', 'A'); 276 | 277 | expect(myEnum.get(4)).to.have.property('value', 4); 278 | expect(myEnum.get(4)).to.have.property('key', 'C'); 279 | 280 | }); 281 | 282 | describe('undefined', function() { 283 | 284 | it('for null', function() { 285 | expect(myEnum.get(null)).to.be(undefined); 286 | }); 287 | 288 | it('for undefined', function() { 289 | expect(myEnum.get(undefined)).to.be(undefined); 290 | }); 291 | 292 | it('for invalid key/value', function() { 293 | expect(myEnum.get('X')).to.be(undefined); 294 | }); 295 | 296 | }); 297 | 298 | }); 299 | 300 | 301 | describe('call getValue and get', function() { 302 | 303 | it('an enum value by item', function() { 304 | 305 | expect(myEnum.getValue(myEnum.A)).to.be(1); 306 | 307 | expect(myEnum.getValue(myEnum.C)).to.be(4); 308 | 309 | }); 310 | 311 | it('an enum value by key', function() { 312 | 313 | expect(myEnum.getValue('A')).to.be(1); 314 | 315 | expect(myEnum.getValue('C')).to.be(4); 316 | 317 | }); 318 | 319 | it('an enum value by value', function() { 320 | 321 | expect(myEnum.getValue(1)).to.be(1); 322 | 323 | expect(myEnum.getValue(4)).to.be(4); 324 | 325 | }); 326 | 327 | describe('undefined', function() { 328 | 329 | it('for null', function() { 330 | expect(myEnum.getValue(null)).to.be(undefined); 331 | }); 332 | 333 | it('for undefined', function() { 334 | expect(myEnum.getValue(undefined)).to.be(undefined); 335 | }); 336 | 337 | it('for invalid key/value', function() { 338 | expect(myEnum.getValue('X')).to.be(undefined); 339 | }); 340 | 341 | }); 342 | 343 | }); 344 | 345 | describe('call getKey and get', function() { 346 | 347 | it('an enum key by item', function() { 348 | 349 | expect(myEnum.getKey(myEnum.A)).to.be('A'); 350 | 351 | expect(myEnum.getKey(myEnum.C)).to.be('C'); 352 | 353 | }); 354 | 355 | it('an enum value by key', function() { 356 | 357 | expect(myEnum.getKey('A')).to.be('A'); 358 | 359 | expect(myEnum.getKey('C')).to.be('C'); 360 | 361 | }); 362 | 363 | it('an enum value by value', function() { 364 | 365 | expect(myEnum.getKey(1)).to.be('A'); 366 | 367 | expect(myEnum.getKey(4)).to.be('C'); 368 | 369 | }); 370 | 371 | describe('undefined', function() { 372 | 373 | it('for null', function() { 374 | expect(myEnum.getKey(null)).to.be(undefined); 375 | }); 376 | 377 | it('for undefined', function() { 378 | expect(myEnum.getKey(undefined)).to.be(undefined); 379 | }); 380 | 381 | it('for invalid key/value', function() { 382 | expect(myEnum.getKey('X')).to.be(undefined); 383 | }); 384 | 385 | }); 386 | }); 387 | 388 | }); 389 | 390 | describe('on an enum item it should be possible to', function() { 391 | 392 | it('call toString and get the key', function() { 393 | 394 | expect(myEnum.A.toString()).to.be('A'); 395 | 396 | }); 397 | 398 | it('call toJSON and get the key', function() { 399 | 400 | expect(myEnum.A.toJSON()).to.be('A'); 401 | 402 | }); 403 | 404 | it('call valueOf and get the value', function() { 405 | 406 | expect(myEnum.A.valueOf()).to.be(myEnum.A.value); 407 | 408 | }); 409 | 410 | it('use JavaScript | operator', function() { 411 | 412 | expect(myEnum.A | myEnum.B).to.be(myEnum.getValue('A | B')); 413 | 414 | expect(myEnum.A | myEnum.C).to.be(myEnum.getValue('A | C')); 415 | 416 | expect(myEnum.A | myEnum.B | myEnum.C).to.be(myEnum.getValue('A | B | C')); 417 | 418 | }); 419 | 420 | it('stringify JSON', function() { 421 | 422 | expect(JSON.stringify(myEnum.A)).to.be('"A"'); 423 | 424 | }); 425 | 426 | }); 427 | 428 | }); 429 | 430 | describe('on an enum object', function(){ 431 | 432 | var frozenEnum; 433 | 434 | before(function(){ 435 | frozenEnum = new e({'A':1, 'B':2, 'C':4}, { freeze: true }); 436 | }); 437 | 438 | if (envSupportsFreezing()) { 439 | 440 | it('can not extend after creation', function() { 441 | 442 | var extendMyEnum = Object.isExtensible(frozenEnum); 443 | expect(extendMyEnum).to.be(false); 444 | 445 | }); 446 | 447 | it('does not accept changes to existing property values, throws', function() { 448 | 449 | expect(frozenEnum).to.have.property('C'); 450 | expect(function() { 451 | frozenEnum['C'] = 3; 452 | }).to.throwError("The value can not be set; Enum Type is not extensible."); 453 | expect(function() { 454 | Object.defineProperty(frozenEnum, 'C', {value: 3, writable:true, configurable: true}); 455 | }).to.throwError(); 456 | expect(frozenEnum.get('C')).to.have.property('value', 4); 457 | expect(frozenEnum).to.be(frozenEnum); 458 | 459 | }); 460 | 461 | it('can not define new properties, throws', function() { 462 | 463 | expect(function() { 464 | Object.defineProperty(frozenEnum, 'D', {writable: true, enumerable:true}); 465 | }).to.throwError(); 466 | expect(frozenEnum.D).to.be(undefined); 467 | expect(frozenEnum).not.to.have.property('D'); 468 | expect(frozenEnum).to.be(frozenEnum); 469 | 470 | }); 471 | 472 | it('is persistent to deletes', function() { 473 | 474 | var deleteEnumItem = delete frozenEnum['A']; 475 | expect(deleteEnumItem).to.be(false); 476 | expect(frozenEnum).to.have.property('A'); 477 | expect(frozenEnum.get('A')).to.have.property('value', 1); 478 | expect(frozenEnum).to.be(frozenEnum); 479 | 480 | }); 481 | } 482 | 483 | it('creates unique identity for each property', function() { 484 | 485 | var myEnum1 = new e({'A':1, 'B':2, 'C':4}); 486 | var myEnum2 = new e({'A':1, 'B':2, 'C':4}); 487 | expect(myEnum1.A).not.to.equal(myEnum2.A); 488 | expect(myEnum1.B).not.to.equal(myEnum2.B); 489 | expect(myEnum1.C).not.to.equal(myEnum2.C); 490 | expect(myEnum1).not.to.equal(myEnum2); 491 | 492 | }); 493 | 494 | }); 495 | 496 | describe('being flagged', function() { 497 | 498 | var myFlaggedEnum; 499 | 500 | before(function() { 501 | myFlaggedEnum = new e({'A': 1, 'B': 2, 'C': 4}); 502 | }); 503 | 504 | it('it should get the flagged value', function() { 505 | 506 | expect(myFlaggedEnum.get(1)).to.be(myFlaggedEnum.A); 507 | expect(myFlaggedEnum.get(2)).to.be(myFlaggedEnum.B); 508 | expect(myFlaggedEnum.get(3).is('A | B')).to.be(true); 509 | 510 | }); 511 | 512 | }); 513 | 514 | describe('not being flagged', function() { 515 | 516 | var myNonFlaggedEnum; 517 | 518 | before(function() { 519 | myNonFlaggedEnum = new e({'0': 0, 'A': 1, 'B': 2, 'B2': 3, 'C': 4}); 520 | }); 521 | 522 | it('it should not get the flagged value', function() { 523 | 524 | expect(myNonFlaggedEnum.get(1)).to.be(myNonFlaggedEnum.A); 525 | expect(myNonFlaggedEnum.get(2)).to.be(myNonFlaggedEnum.B); 526 | expect(myNonFlaggedEnum.get(3)).to.be(myNonFlaggedEnum.B2); 527 | 528 | }); 529 | 530 | describe('getting a non matching value', function() { 531 | 532 | it('it should return undefined', function() { 533 | 534 | expect(myNonFlaggedEnum.get(5)).to.be(undefined); 535 | 536 | }); 537 | 538 | }); 539 | 540 | }); 541 | 542 | describe('and getting an item of it from another enum', function () { 543 | 544 | it('it should return undefined', function() { 545 | 546 | var myEnum1 = new e(['A', 'B', 'C']); 547 | 548 | var myEnum2 = new e({'A': 1, 'B': 2, 'C': 4}); 549 | 550 | expect(myEnum2.get(myEnum1.A)).to.be(undefined); 551 | 552 | }); 553 | 554 | }); 555 | 556 | describe('ref Type interface', function () { 557 | 558 | it('should define a `size` Number', function () { 559 | 560 | var myEnum = new e(['A', 'B', 'C']); 561 | 562 | expect(myEnum.size).to.be.a('number'); 563 | 564 | }); 565 | 566 | it('should define an `indirection` Number', function () { 567 | 568 | var myEnum = new e(['A', 'B', 'C']); 569 | 570 | expect(myEnum.indirection).to.be.a('number'); 571 | 572 | }); 573 | 574 | it('should work with Buffer for `get()`', function () { 575 | 576 | var myEnum = new e(['A', 'B', 'C']); 577 | var buffer = new Buffer(myEnum.size); 578 | 579 | buffer['writeUInt32' + endianness](myEnum.B.value, 0); 580 | 581 | expect(myEnum.get(buffer)).to.be(myEnum.B); 582 | 583 | }); 584 | 585 | it('should work with Buffer for `set()`', function () { 586 | 587 | var myEnum = new e(['A', 'B', 'C']); 588 | var buffer = new Buffer(myEnum.size); 589 | 590 | myEnum.set(buffer, 0, myEnum.B); 591 | 592 | expect(buffer['readUInt32' + endianness](0)).to.be(myEnum.B.value); 593 | 594 | }); 595 | 596 | it('should extend with another array', function() { 597 | 598 | var myEnum = new e(['A', 'B', 'C']); 599 | 600 | var assignedValues = { D: 8, E: 16, F: 32 }; 601 | myEnum.extend(['D', 'E', 'F']); 602 | 603 | expect(myEnum.D.value).to.eql(assignedValues.D); 604 | expect(myEnum.E.value).to.eql(assignedValues.E); 605 | expect(myEnum.F.value).to.eql(assignedValues.F); 606 | }); 607 | 608 | }); 609 | 610 | describe('being not case sensitive', function() { 611 | 612 | var myEnum = new e(['One', 'tWo', 'ThrEE'], { ignoreCase: true }); 613 | 614 | it('it should work correctly even if not requesting exactly the same key value', function() { 615 | 616 | expect(myEnum.get('one').value).to.be(myEnum.One.value); 617 | expect(myEnum.get('two').value).to.be(myEnum.tWo.value); 618 | expect(myEnum.get('THREE').value).to.be(myEnum.ThrEE.value); 619 | 620 | expect(myEnum.One.is('onE')).to.be(true); 621 | expect(myEnum.tWo.is('Two')).to.be(true); 622 | expect(myEnum.ThrEE.is('three')).to.be(true); 623 | 624 | expect(myEnum.One.has('onE')).to.be(true); 625 | expect(myEnum.tWo.has('Two')).to.be(true); 626 | expect(myEnum.ThrEE.has('three')).to.be(true); 627 | 628 | }); 629 | 630 | }); 631 | 632 | describe('with a reserved enumitem name', function() { 633 | var reservedKeys = [ '_options', 'get', 'getKey', 'getValue', 'enums', 'isFlaggable' ]; 634 | 635 | it('throws an error', function() { 636 | for (var k = 0; k < reservedKeys.length; k++) { 637 | 638 | expect(function(){ new e([reservedKeys[k]]); }).to.throwError(new RegExp(reservedKeys[k])); 639 | 640 | } 641 | }); 642 | 643 | it('does not throw an error for `name`', function() { 644 | 645 | expect(function(){ new e(['name']); }).not.to.throwError(); 646 | 647 | }); 648 | 649 | }); 650 | 651 | describe('with a custom name', function() { 652 | 653 | it('can be given as second argument', function() { 654 | var myEnum = new e(['oneFish', 'twoFish'], 'RedFish'); 655 | 656 | expect(myEnum.name).to.be('RedFish'); 657 | }); 658 | 659 | it('can be given as an option', function() { 660 | var myEnum = new e(['oneFish', 'twoFish'], { name: 'BlueFish' }); 661 | 662 | expect(myEnum.name).to.be('BlueFish'); 663 | }); 664 | 665 | it('cannot accept an enumitem also named `name`', function() { 666 | expect(function(){ new e(['name'], 'customName'); }).to.throwError(/name/); 667 | }); 668 | 669 | }); 670 | 671 | }); 672 | 673 | describe('iterating an enum', function() { 674 | var values = ['A', 'B', 'D'] 675 | var myEnum = new e(values) 676 | 677 | it('should iterate through the enum items', function() { 678 | var index = 0 679 | for (var enumItem of myEnum) { 680 | expect(enumItem.key).to.equal(values[index]) 681 | expect(enumItem).to.equal(myEnum.get(enumItem.key)) 682 | index++ 683 | } 684 | expect(index).to.equal(values.length) 685 | }) 686 | }) 687 | 688 | }); 689 | })(this); 690 | -------------------------------------------------------------------------------- /test/package.json: -------------------------------------------------------------------------------- 1 | {"type":"commonjs"} 2 | -------------------------------------------------------------------------------- /test/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Mocha Tests 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 20 | 21 | 22 |
23 | 24 | 25 | --------------------------------------------------------------------------------