diff --git a/.gitignore b/.gitignore index a261f29..a266600 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ dist/* +package-lock.json +yarn.lock +node_modules diff --git a/package-lock.json b/package-lock.json deleted file mode 100644 index f740bd8..0000000 --- a/package-lock.json +++ /dev/null @@ -1,311 +0,0 @@ -{ - "name": "@bitarray/typedarray", - "version": "1.0.2", - "lockfileVersion": 2, - "requires": true, - "packages": { - "": { - "name": "@bitarray/typedarray", - "version": "1.0.2", - "license": "ISC", - "devDependencies": { - "ts-node": "^10.7.0", - "typescript": "^4.2.4" - } - }, - "node_modules/@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true, - "engines": { - "node": ">= 12" - } - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-consumer": "0.8.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "node_modules/@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "node_modules/@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "node_modules/@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "node_modules/@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true, - "peer": true - }, - "node_modules/acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true, - "bin": { - "acorn": "bin/acorn" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "node_modules/create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "node_modules/diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true, - "engines": { - "node": ">=0.3.1" - } - }, - "node_modules/make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "node_modules/ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", - "dev": true, - "dependencies": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" - }, - "bin": { - "ts-node": "dist/bin.js", - "ts-node-cwd": "dist/bin-cwd.js", - "ts-node-esm": "dist/bin-esm.js", - "ts-node-script": "dist/bin-script.js", - "ts-node-transpile-only": "dist/bin-transpile.js", - "ts-script": "dist/bin-script-deprecated.js" - }, - "peerDependencies": { - "@swc/core": ">=1.2.50", - "@swc/wasm": ">=1.2.50", - "@types/node": "*", - "typescript": ">=2.7" - }, - "peerDependenciesMeta": { - "@swc/core": { - "optional": true - }, - "@swc/wasm": { - "optional": true - } - } - }, - "node_modules/typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=4.2.0" - } - }, - "node_modules/v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", - "dev": true - }, - "node_modules/yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true, - "engines": { - "node": ">=6" - } - } - }, - "dependencies": { - "@cspotcode/source-map-consumer": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-consumer/-/source-map-consumer-0.8.0.tgz", - "integrity": "sha512-41qniHzTU8yAGbCp04ohlmSrZf8bkf/iJsl3V0dRGsQN/5GFfx+LbCSsCpp2gqrqjTVg/K6O8ycoV35JIwAzAg==", - "dev": true - }, - "@cspotcode/source-map-support": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.7.0.tgz", - "integrity": "sha512-X4xqRHqN8ACt2aHVe51OxeA2HjbcL4MqFqXkrmQszJ1NOUuUu5u6Vqx/0lZSVNku7velL5FC/s5uEAj1lsBMhA==", - "dev": true, - "requires": { - "@cspotcode/source-map-consumer": "0.8.0" - } - }, - "@tsconfig/node10": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/@tsconfig/node10/-/node10-1.0.8.tgz", - "integrity": "sha512-6XFfSQmMgq0CFLY1MslA/CPUfhIL919M1rMsa5lP2P097N2Wd1sSX0tx1u4olM16fLNhtHZpRhedZJphNJqmZg==", - "dev": true - }, - "@tsconfig/node12": { - "version": "1.0.9", - "resolved": "https://registry.npmjs.org/@tsconfig/node12/-/node12-1.0.9.tgz", - "integrity": "sha512-/yBMcem+fbvhSREH+s14YJi18sp7J9jpuhYByADT2rypfajMZZN4WQ6zBGgBKp53NKmqI36wFYDb3yaMPurITw==", - "dev": true - }, - "@tsconfig/node14": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@tsconfig/node14/-/node14-1.0.1.tgz", - "integrity": "sha512-509r2+yARFfHHE7T6Puu2jjkoycftovhXRqW328PDXTVGKihlb1P8Z9mMZH04ebyajfRY7dedfGynlrFHJUQCg==", - "dev": true - }, - "@tsconfig/node16": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/@tsconfig/node16/-/node16-1.0.2.tgz", - "integrity": "sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==", - "dev": true - }, - "@types/node": { - "version": "17.0.23", - "resolved": "https://registry.npmjs.org/@types/node/-/node-17.0.23.tgz", - "integrity": "sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==", - "dev": true, - "peer": true - }, - "acorn": { - "version": "8.7.0", - "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.7.0.tgz", - "integrity": "sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==", - "dev": true - }, - "acorn-walk": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.2.0.tgz", - "integrity": "sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==", - "dev": true - }, - "arg": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/arg/-/arg-4.1.3.tgz", - "integrity": "sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==", - "dev": true - }, - "create-require": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/create-require/-/create-require-1.1.1.tgz", - "integrity": "sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==", - "dev": true - }, - "diff": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", - "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", - "dev": true - }, - "make-error": { - "version": "1.3.6", - "resolved": "https://registry.npmjs.org/make-error/-/make-error-1.3.6.tgz", - "integrity": "sha512-s8UhlNe7vPKomQhC1qFelMokr/Sc3AgNbso3n74mVPA5LTZwkB9NlXf4XPamLxJE8h0gh73rM94xvwRT2CVInw==", - "dev": true - }, - "ts-node": { - "version": "10.7.0", - "resolved": "https://registry.npmjs.org/ts-node/-/ts-node-10.7.0.tgz", - "integrity": "sha512-TbIGS4xgJoX2i3do417KSaep1uRAW/Lu+WAL2doDHC0D6ummjirVOXU5/7aiZotbQ5p1Zp9tP7U6cYhA0O7M8A==", - "dev": true, - "requires": { - "@cspotcode/source-map-support": "0.7.0", - "@tsconfig/node10": "^1.0.7", - "@tsconfig/node12": "^1.0.7", - "@tsconfig/node14": "^1.0.0", - "@tsconfig/node16": "^1.0.2", - "acorn": "^8.4.1", - "acorn-walk": "^8.1.1", - "arg": "^4.1.0", - "create-require": "^1.1.0", - "diff": "^4.0.1", - "make-error": "^1.1.1", - "v8-compile-cache-lib": "^3.0.0", - "yn": "3.1.1" - } - }, - "typescript": { - "version": "4.6.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.6.3.tgz", - "integrity": "sha512-yNIatDa5iaofVozS/uQJEl3JRWLKKGJKh6Yaiv0GLGSuhpFJe7P3SbHZ8/yjAHRQwKRoA6YZqlfjXWmVzoVSMw==", - "dev": true - }, - "v8-compile-cache-lib": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.0.tgz", - "integrity": "sha512-mpSYqfsFvASnSn5qMiwrr4VKfumbPyONLCOPmsR3A6pTY/r0+tSaVbgPWSAIuzbk3lCTa+FForeTiO+wBQGkjA==", - "dev": true - }, - "yn": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", - "integrity": "sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q==", - "dev": true - } - } -} diff --git a/package.json b/package.json index 838e796..6ccfb0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@bitarray/typedarray", - "version": "1.0.2", + "version": "1.0.3", "description": "A BitArray object exhibiting the interface of standard ecmascript TypedArray's", "typings": "./dist/esm/bit-typedarray.d.ts", "exports": { diff --git a/src/bit-typedarray.ts b/src/bit-typedarray.ts index 8367b95..f13db3f 100644 --- a/src/bit-typedarray.ts +++ b/src/bit-typedarray.ts @@ -9,13 +9,13 @@ // it should be fairly easy to implement whatever is needed from the current // base. -type bit = 0|1; +type bit = 0 | 1; // Everytime we need to read/write from/to the buffer, we need a viewer. // It would be simple, but very inefficient to create a viewer each time. // So instead, we create one (a Uint32Array instance), once for all, // and resort to a weakmap to allow retrieving it later on. -const _views = new WeakMap(); +const _views = new WeakMap(); // // We could make it available to the outside world so it can benefit as well. // // Should we prefer to keep this private, it would also be possible. @@ -24,22 +24,22 @@ const _views = new WeakMap(); // export { _views }; // store ownKeys computation to avoid repeating each time -const _keys = new WeakMap(); +const _keys = new WeakMap(); // for my proxy const handlers = { - get: function( target: BitArray, prop: string|symbol ) { + get: function (target: BitArray, prop: string | symbol) { - if( typeof prop === "string" ) { - const index = Number( prop ); - if( index === Math.trunc(index) && index >= 0 && index < target.length ) { - const [intIndex, bitMask] = bitIndex2coord( index ); - return Number( Boolean( _views.get( target.buffer )[ intIndex ] & bitMask ) ); + if (typeof prop === "string") { + const index = Number(prop); + if (index === Math.trunc(index) && index >= 0 && index < target.length) { + const [intIndex, bitMask] = bitIndex2coord(index); + return Number(Boolean(_views.get(target.buffer)[intIndex] & bitMask)); } } - return Reflect.get( target, prop ); + return Reflect.get(target, prop); }, // In standard typed arrays, except for the Uint8clamped type, values @@ -47,15 +47,15 @@ const handlers = { // a Uint8 results in the value 1 (== 257 % 0xFF). // Here, any value coerced to a boolean that is truthy will result // in setting value 1; 0 otherwise. - set: function( target: BitArray, prop: string|symbol, value: bit ) { - - if( typeof prop === "string" ) { - const index = Number( prop ); - if( index === Math.trunc(index) && index >= 0 && index < target.length ) { - const view = _views.get( target.buffer ); - const [intIndex, bitMask] = bitIndex2coord( index ); - view[ intIndex ] = Boolean(value) ? view[ intIndex ] | bitMask - : view[ intIndex ] & ~bitMask; + set: function (target: BitArray, prop: string | symbol, value: bit) { + + if (typeof prop === "string") { + const index = Number(prop); + if (index === Math.trunc(index) && index >= 0 && index < target.length) { + const view = _views.get(target.buffer); + const [intIndex, bitMask] = bitIndex2coord(index); + view[intIndex] = Boolean(value) ? view[intIndex] | bitMask + : view[intIndex] & ~bitMask; return true; } } @@ -66,15 +66,15 @@ const handlers = { // We want to be able to use e.g. for( let i in ... ) // so ownKeys must return the indexes ownKeys: (target: BitArray): string[] => { - let keys: string[] = _keys.get( target ); + let keys: string[] = _keys.get(target); - if( !keys ) + if (!keys) // construct and store keys once for all _keys.set( target, - keys = Array( target.length ) - .fill(void 0) - .map( (_,i) => i.toString() ) + keys = Array(target.length) + .fill(void 0) + .map((_, i) => i.toString()) ); return keys @@ -82,37 +82,37 @@ const handlers = { // Needed to make ownKeys work as expected. // see https://javascript.info/proxy#iteration-with-ownkeys-and-getownpropertydescriptor - getOwnPropertyDescriptor: (/*target: BitArray, prop*/): object => ( { - enumerable: true, - configurable: true - }) + getOwnPropertyDescriptor: (/*target: BitArray, prop*/): object => ({ + enumerable: true, + configurable: true + }) }; class BitArray implements Iterable { - buffer : ArrayBuffer; + buffer: ArrayBuffer; byteLength: number; byteOffset: number; - length : number; - prototype : object; - [Symbol.iterator]: ()=>Iterator; + length: number; + prototype: object; + [Symbol.iterator]: () => Iterator; [index: number]: bit; - static BYTES_PER_ELEMENT = 1/8; + static BYTES_PER_ELEMENT = 1 / 8; // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from - static from( source: Iterable /*, mapFn?, thisArg?*/ ) { - return new this( source ); + static from(source: Iterable /*, mapFn?, thisArg?*/) { + return new this(source); } // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of - static of( ...items ) { + static of(...items) { // let ret = new this( items.length ); // for( let i in items ) ret[i] = Number( (items[i]) ); // return ret; // simplified into - return this.from( items ); + return this.from(items); } /** @@ -126,34 +126,50 @@ class BitArray implements Iterable { // by using a proxy. The object _itself_ must be a proxy. // It is NOT possible to extend Proxy's. However, it is possible to return // a proxy from the constructor. - constructor( arg: number /*| TypedArray @todo */ | Iterable ) { - - let byteOffset = 0; - let byteLength: number; - let buffer: ArrayBuffer; - let length = 0; + constructor(data: Iterable | number, byteOffset?: number, length?: number) { + + if (length === undefined){ + if (typeof data === "number") { + // only length is specified, but as argument data + length = data; + } else { + // data is Iterable, and length is not defined. + length = 0; + for (let _ of data as Iterable) length++; + } + } - const argIsIterable = Symbol.iterator in Object( arg ) + //check for invalid lengths + if (length < 0) { + throw new RangeError("invalid array length"); + } + + // set byteOffset if it was not defined + if (byteOffset === undefined) { + byteOffset = 0; + } + + // although there is much less utility to having a byte offset with a boolean + // TypedArray, in order to maintain consistency with the target + // the byteOffset must be converted to a bitOffset + const bitOffset = 8*byteOffset; - if( argIsIterable ) - for(let _ of arg as Iterable) length++; - else { - length = Math.trunc( arg as number ); + const byteLength:number = Math.ceil(Math.ceil(length/8 - byteOffset)/4)*4 - if( length < 0 ) - throw new RangeError("invalid array length"); + // if the byteoffset is longer than length, then throw and error + if (bitOffset >= length && bitOffset > 0){ + throw new RangeError("invalid byteOffset"); } - byteLength = ( ( length-1 >> 5 ) + 1 ) * 4; - buffer = new ArrayBuffer( byteLength ); + let buffer = new ArrayBuffer(byteLength); // by default, properties are not writable, which is what I need // however, I need to have them configurable, as per https://stackoverflow.com/a/42876020 - Object.defineProperties( this, { - "byteOffset": { value: byteOffset , configurable: true }, - "byteLength": { value: byteLength , configurable: true }, - "buffer": { value: buffer , configurable: true }, - "length": { value: length , configurable: true } + Object.defineProperties(this, { + "byteOffset": { value: byteOffset, configurable: true }, + "byteLength": { value: byteLength, configurable: true }, + "buffer": { value: buffer, configurable: true }, + "length": { value: length-bitOffset, configurable: true } }); // store once for all a viewer for this buffer (see above) @@ -170,15 +186,20 @@ class BitArray implements Iterable { // I have not thought too much about it yet: it seems a very corner // case when it comes to usage of bit arrays; and such construction // is not supported at this stage anyway. - _views.set( this.buffer, new Uint32Array( this.buffer ) ); - - let ret = Reflect.construct( Proxy, [this,handlers] ); - - if( argIsIterable ) - for( let i in arg as Iterable) - // beware Boolean("0") === true, so make sure to convert to number first; - ret[i] = Number( arg[i] ); - + _views.set(this.buffer, new Uint32Array(this.buffer)); + + let ret = Reflect.construct(Proxy, [this, handlers]); + if (typeof data !== "number"){ + for (let i = 0; i< length-bitOffset; i++){ + if(data[i+bitOffset] === undefined || data[i+bitOffset] === null){ + ret[i] = Number(0); + } else { + // beware Boolean("0") === true, so make sure to convert to number first; + ret[i] = Number(data[i+bitOffset]); + } + } + } + return ret; } @@ -200,21 +221,21 @@ class BitArray implements Iterable { // .join("") // .trim(); var ret = ""; - for( let i=0; i( callback: ( value:bit, index:number, thisArg?:T ) => any, thisArg?:this|T ) { - if( typeof callback !== "function" ) + forEach(callback: (value: bit, index: number, thisArg?: T) => any, thisArg?: this | T) { + if (typeof callback !== "function") throw new TypeError(callback + " is not a function"); thisArg = thisArg || this; - for( let i=0; i { // Note: this is an experimental feature. // // Inspired by https://github.com/tc39/proposal-relative-indexing-method#polyfill - at( index: number ): bit|undefined { - index = Math.trunc( index ) || 0; + at(index: number): bit | undefined { + index = Math.trunc(index) || 0; // If a negative number is used, the element returned // will be found by counting back from the end of the array. - if( index<0 ) index += this.length; + if (index < 0) index += this.length; // out-of-bounds access is guaranteed to return undefined - if( index<0 || index>=this.length ) return void 0; + if (index < 0 || index >= this.length) return void 0; // const [intIndex, bitMask] = bitIndex2coord( index ); // return Number( _views.get( this.buffer )[ intIndex ] & bitMask ); @@ -246,33 +267,33 @@ class BitArray implements Iterable { // // Should we keep allowing an offset? Obviously, this is according to // the native TypedArray's, but can it have any use for BitArrays? - set( source: bit[], offset: number = 0 ) { + set(source: bit[], offset: number = 0) { - if( offset<0 || offset>=this.length ) + if (offset < 0 || offset >= this.length) throw new RangeError("invalid or out-of-range index"); - if( offset+source.length > this.length ) + if (offset + source.length > this.length) throw new RangeError("source array is too long"); // const view = _views.get( this.buffer ); - for( let i=0; i{ + next: () => { return currentIndex < this.length ? - { done: false, value: this[ currentIndex++ ] } - : { done: true } as IteratorResult; + { done: false, value: this[currentIndex++] } + : { done: true } as IteratorResult; } }; }; @@ -286,10 +307,10 @@ class BitArray implements Iterable { * @returns the Uint32 index and bit mask that can be used by a Uint32 viewer * to access the index'th value of the bit array. */ - function bitIndex2coord( index: number ): [number, number] { +function bitIndex2coord(index: number): [number, number] { return [ index >> 5, // divide by 32 - 1 << ( index & 31 ) // modulo 32 + 1 << (index & 31) // modulo 32 ]; } diff --git a/test/suite.ts b/test/suite.ts index 2efd496..a87d42a 100644 --- a/test/suite.ts +++ b/test/suite.ts @@ -12,12 +12,17 @@ const bits = new BitArray( length ); const instantiating = { "new BitArray( length )": bits instanceof BitArray, "length is set": bits.length === length, - "empty bit array has length 0": new BitArray(0) .length === 0, + "empty bit array has length 0": new BitArray(0).length === 0, + "new BitArray instanceof BitArray": new BitArray("011010") instanceof BitArray, + "new BitArray(iterable) has correct length": new BitArray("011010").length === 6, + "new BitArray(iterable) sets correct values": new BitArray("011010").toString() === "011010", + "new BitArray(iterable,offset,length) sets correct values": new BitArray("011010",0,6).toString() === "011010", + + "new BitArray(iterable,offset,length) has correct length": new BitArray("011010",0,9).length === 9, + "new BitArray(iterable,offset,length) with offset has correct length": new BitArray("1010101001101010",1,16).length === 8, "new BitArray( iterable )": new BitArray("011010") instanceof BitArray && new BitArray("011010") .length === 6 }; - - /** suite 2 */ const reading_writing = { "default value set to 0": bits[0] === 0 && bits[length-1] === 0,