Comparing version 4.1.0 to 4.2.0
@@ -21,16 +21,18 @@ interface BitFieldOptions { | ||
buffer: Uint8Array; | ||
/** The number of bits in the bitfield. */ | ||
get length(): number; | ||
/** | ||
* Constructs a BitField. | ||
* | ||
* | ||
* @param data Either a number representing the maximum number of supported bytes, or a Uint8Array. | ||
* @param data Either a number representing the maximum number of supported bits, or a Uint8Array. | ||
* @param opts Options for the bitfield. | ||
*/ | ||
constructor(data?: number | Uint8Array, opts?: BitFieldOptions); | ||
constructor(data?: number | Uint8Array, options?: BitFieldOptions); | ||
/** | ||
* Get a particular bit. | ||
* | ||
* @param i Bit index to retrieve. | ||
* @param bitIndex Bit index to retrieve. | ||
* @returns A boolean indicating whether the `i`th bit is set. | ||
*/ | ||
get(i: number): boolean; | ||
get(bitIndex: number): boolean; | ||
/** | ||
@@ -41,16 +43,29 @@ * Set a particular bit. | ||
* | ||
* @param i Bit index to set. | ||
* @param bitIndex Bit index to set. | ||
* @param value Value to set the bit to. Defaults to `true`. | ||
*/ | ||
set(i: number, value?: boolean): void; | ||
set(bitIndex: number, value?: boolean): void; | ||
/** | ||
* Sets a value or an array of values. | ||
* | ||
* @param array An array of booleans to set. | ||
* @param offset The bit offset at which the values are to be written. | ||
*/ | ||
setAll(array: ArrayLike<boolean>, offset?: number): void; | ||
/** | ||
* Loop through the bits in the bitfield. | ||
* | ||
* @param fn Function to be called with the bit value and index. | ||
* @param callbackfn Function to be called with the bit value and index. | ||
* @param start Index of the first bit to look at. | ||
* @param end Index of the first bit that should no longer be considered. | ||
*/ | ||
forEach(fn: (bit: boolean, index: number) => void, start?: number, end?: number): void; | ||
forEach(callbackfn: (bit: boolean, index: number) => void, start?: number, end?: number): void; | ||
/** | ||
* Check if all bits in the Bitfield are unset. | ||
* | ||
* @returns A boolean indicating whether all bits are unset. | ||
*/ | ||
isEmpty(): boolean; | ||
} | ||
export {}; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,19 +0,30 @@ | ||
function getByteSize(num) { | ||
let out = num >> 3; | ||
if (num % 8 !== 0) | ||
out++; | ||
return out; | ||
/** | ||
* Converts a number of bits to a number of bytes. | ||
* | ||
* @param numberOfBits The number of bits to convert. | ||
* @returns The number of bytes that are needed to store the given number of bits. | ||
*/ | ||
function bitsToBytes(numberOfBits) { | ||
return (numberOfBits >> 3) + Number(numberOfBits % 8 !== 0); | ||
} | ||
export default class BitField { | ||
/** The number of bits in the bitfield. */ | ||
get length() { | ||
return this.buffer.length << 3; | ||
} | ||
/** | ||
* Constructs a BitField. | ||
* | ||
* | ||
* @param data Either a number representing the maximum number of supported bytes, or a Uint8Array. | ||
* @param data Either a number representing the maximum number of supported bits, or a Uint8Array. | ||
* @param opts Options for the bitfield. | ||
*/ | ||
constructor(data = 0, opts) { | ||
const grow = opts === null || opts === void 0 ? void 0 : opts.grow; | ||
this.grow = (grow && isFinite(grow) && getByteSize(grow)) || grow || 0; | ||
constructor(data = 0, options) { | ||
const grow = options === null || options === void 0 ? void 0 : options.grow; | ||
this.grow = grow | ||
? Number.isFinite(grow) | ||
? bitsToBytes(grow) | ||
: grow | ||
: 0; | ||
this.buffer = | ||
typeof data === "number" ? new Uint8Array(getByteSize(data)) : data; | ||
typeof data === "number" ? new Uint8Array(bitsToBytes(data)) : data; | ||
} | ||
@@ -23,8 +34,9 @@ /** | ||
* | ||
* @param i Bit index to retrieve. | ||
* @param bitIndex Bit index to retrieve. | ||
* @returns A boolean indicating whether the `i`th bit is set. | ||
*/ | ||
get(i) { | ||
const j = i >> 3; | ||
return j < this.buffer.length && !!(this.buffer[j] & (128 >> i % 8)); | ||
get(bitIndex) { | ||
const byteIndex = bitIndex >> 3; | ||
return (byteIndex < this.buffer.length && | ||
!!(this.buffer[byteIndex] & (128 >> bitIndex % 8))); | ||
} | ||
@@ -36,12 +48,12 @@ /** | ||
* | ||
* @param i Bit index to set. | ||
* @param bitIndex Bit index to set. | ||
* @param value Value to set the bit to. Defaults to `true`. | ||
*/ | ||
set(i, value = true) { | ||
const j = i >> 3; | ||
set(bitIndex, value = true) { | ||
const byteIndex = bitIndex >> 3; | ||
if (value) { | ||
if (this.buffer.length < j + 1) { | ||
const length = Math.max(j + 1, Math.min(2 * this.buffer.length, this.grow)); | ||
if (length <= this.grow) { | ||
const newBuffer = new Uint8Array(length); | ||
if (byteIndex >= this.buffer.length) { | ||
const newLength = Math.max(byteIndex + 1, Math.min(2 * this.buffer.length, this.grow)); | ||
if (newLength <= this.grow) { | ||
const newBuffer = new Uint8Array(newLength); | ||
newBuffer.set(this.buffer); | ||
@@ -51,24 +63,77 @@ this.buffer = newBuffer; | ||
} | ||
// Set | ||
this.buffer[j] |= 128 >> i % 8; | ||
this.buffer[byteIndex] |= 128 >> bitIndex % 8; | ||
} | ||
else if (j < this.buffer.length) { | ||
// Clear | ||
this.buffer[j] &= ~(128 >> i % 8); | ||
else if (byteIndex < this.buffer.length) { | ||
this.buffer[byteIndex] &= ~(128 >> bitIndex % 8); | ||
} | ||
} | ||
/** | ||
* Sets a value or an array of values. | ||
* | ||
* @param array An array of booleans to set. | ||
* @param offset The bit offset at which the values are to be written. | ||
*/ | ||
setAll(array, offset = 0) { | ||
const targetLength = Math.min(bitsToBytes(offset + array.length), this.grow); | ||
if (this.buffer.length < targetLength) { | ||
const newBuffer = new Uint8Array(targetLength); | ||
newBuffer.set(this.buffer); | ||
this.buffer = newBuffer; | ||
} | ||
let byteIndex = offset >> 3; | ||
let bitMask = 128 >> offset % 8; | ||
for (let index = 0; index < array.length; index++) { | ||
if (array[index]) { | ||
this.buffer[byteIndex] |= bitMask; | ||
} | ||
else { | ||
this.buffer[byteIndex] &= ~bitMask; | ||
} | ||
if (bitMask === 1) { | ||
byteIndex += 1; | ||
if (byteIndex >= this.buffer.length) { | ||
break; | ||
} | ||
bitMask = 128; | ||
} | ||
else { | ||
bitMask >>= 1; | ||
} | ||
} | ||
} | ||
/** | ||
* Loop through the bits in the bitfield. | ||
* | ||
* @param fn Function to be called with the bit value and index. | ||
* @param callbackfn Function to be called with the bit value and index. | ||
* @param start Index of the first bit to look at. | ||
* @param end Index of the first bit that should no longer be considered. | ||
*/ | ||
forEach(fn, start = 0, end = this.buffer.length * 8) { | ||
for (let i = start, j = i >> 3, y = 128 >> i % 8, byte = this.buffer[j]; i < end; i++) { | ||
fn(!!(byte & y), i); | ||
y = y === 1 ? ((byte = this.buffer[++j]), 128) : y >> 1; | ||
forEach(callbackfn, start = 0, end = this.buffer.length * 8) { | ||
let byteIndex = start >> 3; | ||
let bitMask = 128 >> start % 8; | ||
for (let bitIndex = start; bitIndex < end; bitIndex++) { | ||
callbackfn(!!(this.buffer[byteIndex] & bitMask), bitIndex); | ||
if (bitMask === 1) { | ||
byteIndex += 1; | ||
bitMask = 128; | ||
} | ||
else { | ||
bitMask >>= 1; | ||
} | ||
} | ||
} | ||
/** | ||
* Check if all bits in the Bitfield are unset. | ||
* | ||
* @returns A boolean indicating whether all bits are unset. | ||
*/ | ||
isEmpty() { | ||
for (let i = 0; i < this.buffer.length; i++) { | ||
if (this.buffer[i] !== 0) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
//# sourceMappingURL=index.js.map |
@@ -21,16 +21,18 @@ interface BitFieldOptions { | ||
buffer: Uint8Array; | ||
/** The number of bits in the bitfield. */ | ||
get length(): number; | ||
/** | ||
* Constructs a BitField. | ||
* | ||
* | ||
* @param data Either a number representing the maximum number of supported bytes, or a Uint8Array. | ||
* @param data Either a number representing the maximum number of supported bits, or a Uint8Array. | ||
* @param opts Options for the bitfield. | ||
*/ | ||
constructor(data?: number | Uint8Array, opts?: BitFieldOptions); | ||
constructor(data?: number | Uint8Array, options?: BitFieldOptions); | ||
/** | ||
* Get a particular bit. | ||
* | ||
* @param i Bit index to retrieve. | ||
* @param bitIndex Bit index to retrieve. | ||
* @returns A boolean indicating whether the `i`th bit is set. | ||
*/ | ||
get(i: number): boolean; | ||
get(bitIndex: number): boolean; | ||
/** | ||
@@ -41,16 +43,29 @@ * Set a particular bit. | ||
* | ||
* @param i Bit index to set. | ||
* @param bitIndex Bit index to set. | ||
* @param value Value to set the bit to. Defaults to `true`. | ||
*/ | ||
set(i: number, value?: boolean): void; | ||
set(bitIndex: number, value?: boolean): void; | ||
/** | ||
* Sets a value or an array of values. | ||
* | ||
* @param array An array of booleans to set. | ||
* @param offset The bit offset at which the values are to be written. | ||
*/ | ||
setAll(array: ArrayLike<boolean>, offset?: number): void; | ||
/** | ||
* Loop through the bits in the bitfield. | ||
* | ||
* @param fn Function to be called with the bit value and index. | ||
* @param callbackfn Function to be called with the bit value and index. | ||
* @param start Index of the first bit to look at. | ||
* @param end Index of the first bit that should no longer be considered. | ||
*/ | ||
forEach(fn: (bit: boolean, index: number) => void, start?: number, end?: number): void; | ||
forEach(callbackfn: (bit: boolean, index: number) => void, start?: number, end?: number): void; | ||
/** | ||
* Check if all bits in the Bitfield are unset. | ||
* | ||
* @returns A boolean indicating whether all bits are unset. | ||
*/ | ||
isEmpty(): boolean; | ||
} | ||
export {}; | ||
//# sourceMappingURL=index.d.ts.map |
134
lib/index.js
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
function getByteSize(num) { | ||
var out = num >> 3; | ||
if (num % 8 !== 0) | ||
out++; | ||
return out; | ||
/** | ||
* Converts a number of bits to a number of bytes. | ||
* | ||
* @param numberOfBits The number of bits to convert. | ||
* @returns The number of bytes that are needed to store the given number of bits. | ||
*/ | ||
function bitsToBytes(numberOfBits) { | ||
return (numberOfBits >> 3) + Number(numberOfBits % 8 !== 0); | ||
} | ||
var BitField = /** @class */ (function () { | ||
/** | ||
* Constructs a BitField. | ||
* | ||
* | ||
* @param data Either a number representing the maximum number of supported bytes, or a Uint8Array. | ||
* @param data Either a number representing the maximum number of supported bits, or a Uint8Array. | ||
* @param opts Options for the bitfield. | ||
*/ | ||
function BitField(data, opts) { | ||
function BitField(data, options) { | ||
if (data === void 0) { data = 0; } | ||
var grow = opts === null || opts === void 0 ? void 0 : opts.grow; | ||
this.grow = (grow && isFinite(grow) && getByteSize(grow)) || grow || 0; | ||
var grow = options === null || options === void 0 ? void 0 : options.grow; | ||
this.grow = grow | ||
? Number.isFinite(grow) | ||
? bitsToBytes(grow) | ||
: grow | ||
: 0; | ||
this.buffer = | ||
typeof data === "number" ? new Uint8Array(getByteSize(data)) : data; | ||
typeof data === "number" ? new Uint8Array(bitsToBytes(data)) : data; | ||
} | ||
Object.defineProperty(BitField.prototype, "length", { | ||
/** The number of bits in the bitfield. */ | ||
get: function () { | ||
return this.buffer.length << 3; | ||
}, | ||
enumerable: false, | ||
configurable: true | ||
}); | ||
/** | ||
* Get a particular bit. | ||
* | ||
* @param i Bit index to retrieve. | ||
* @param bitIndex Bit index to retrieve. | ||
* @returns A boolean indicating whether the `i`th bit is set. | ||
*/ | ||
BitField.prototype.get = function (i) { | ||
var j = i >> 3; | ||
return j < this.buffer.length && !!(this.buffer[j] & (128 >> i % 8)); | ||
BitField.prototype.get = function (bitIndex) { | ||
var byteIndex = bitIndex >> 3; | ||
return (byteIndex < this.buffer.length && | ||
!!(this.buffer[byteIndex] & (128 >> bitIndex % 8))); | ||
}; | ||
@@ -38,13 +54,13 @@ /** | ||
* | ||
* @param i Bit index to set. | ||
* @param bitIndex Bit index to set. | ||
* @param value Value to set the bit to. Defaults to `true`. | ||
*/ | ||
BitField.prototype.set = function (i, value) { | ||
BitField.prototype.set = function (bitIndex, value) { | ||
if (value === void 0) { value = true; } | ||
var j = i >> 3; | ||
var byteIndex = bitIndex >> 3; | ||
if (value) { | ||
if (this.buffer.length < j + 1) { | ||
var length = Math.max(j + 1, Math.min(2 * this.buffer.length, this.grow)); | ||
if (length <= this.grow) { | ||
var newBuffer = new Uint8Array(length); | ||
if (byteIndex >= this.buffer.length) { | ||
var newLength = Math.max(byteIndex + 1, Math.min(2 * this.buffer.length, this.grow)); | ||
if (newLength <= this.grow) { | ||
var newBuffer = new Uint8Array(newLength); | ||
newBuffer.set(this.buffer); | ||
@@ -54,25 +70,79 @@ this.buffer = newBuffer; | ||
} | ||
// Set | ||
this.buffer[j] |= 128 >> i % 8; | ||
this.buffer[byteIndex] |= 128 >> bitIndex % 8; | ||
} | ||
else if (j < this.buffer.length) { | ||
// Clear | ||
this.buffer[j] &= ~(128 >> i % 8); | ||
else if (byteIndex < this.buffer.length) { | ||
this.buffer[byteIndex] &= ~(128 >> bitIndex % 8); | ||
} | ||
}; | ||
/** | ||
* Sets a value or an array of values. | ||
* | ||
* @param array An array of booleans to set. | ||
* @param offset The bit offset at which the values are to be written. | ||
*/ | ||
BitField.prototype.setAll = function (array, offset) { | ||
if (offset === void 0) { offset = 0; } | ||
var targetLength = Math.min(bitsToBytes(offset + array.length), this.grow); | ||
if (this.buffer.length < targetLength) { | ||
var newBuffer = new Uint8Array(targetLength); | ||
newBuffer.set(this.buffer); | ||
this.buffer = newBuffer; | ||
} | ||
var byteIndex = offset >> 3; | ||
var bitMask = 128 >> offset % 8; | ||
for (var index = 0; index < array.length; index++) { | ||
if (array[index]) { | ||
this.buffer[byteIndex] |= bitMask; | ||
} | ||
else { | ||
this.buffer[byteIndex] &= ~bitMask; | ||
} | ||
if (bitMask === 1) { | ||
byteIndex += 1; | ||
if (byteIndex >= this.buffer.length) { | ||
break; | ||
} | ||
bitMask = 128; | ||
} | ||
else { | ||
bitMask >>= 1; | ||
} | ||
} | ||
}; | ||
/** | ||
* Loop through the bits in the bitfield. | ||
* | ||
* @param fn Function to be called with the bit value and index. | ||
* @param callbackfn Function to be called with the bit value and index. | ||
* @param start Index of the first bit to look at. | ||
* @param end Index of the first bit that should no longer be considered. | ||
*/ | ||
BitField.prototype.forEach = function (fn, start, end) { | ||
BitField.prototype.forEach = function (callbackfn, start, end) { | ||
if (start === void 0) { start = 0; } | ||
if (end === void 0) { end = this.buffer.length * 8; } | ||
for (var i = start, j = i >> 3, y = 128 >> i % 8, byte = this.buffer[j]; i < end; i++) { | ||
fn(!!(byte & y), i); | ||
y = y === 1 ? ((byte = this.buffer[++j]), 128) : y >> 1; | ||
var byteIndex = start >> 3; | ||
var bitMask = 128 >> start % 8; | ||
for (var bitIndex = start; bitIndex < end; bitIndex++) { | ||
callbackfn(!!(this.buffer[byteIndex] & bitMask), bitIndex); | ||
if (bitMask === 1) { | ||
byteIndex += 1; | ||
bitMask = 128; | ||
} | ||
else { | ||
bitMask >>= 1; | ||
} | ||
} | ||
}; | ||
/** | ||
* Check if all bits in the Bitfield are unset. | ||
* | ||
* @returns A boolean indicating whether all bits are unset. | ||
*/ | ||
BitField.prototype.isEmpty = function () { | ||
for (var i = 0; i < this.buffer.length; i++) { | ||
if (this.buffer[i] !== 0) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
}; | ||
return BitField; | ||
@@ -79,0 +149,0 @@ }()); |
{ | ||
"name": "bitfield", | ||
"description": "a simple bitfield, compliant with the BitTorrent spec", | ||
"version": "4.1.0", | ||
"version": "4.2.0", | ||
"author": "Felix Boehm <me@feedic.com>", | ||
@@ -27,13 +27,13 @@ "funding": { | ||
"devDependencies": { | ||
"@types/jest": "^27.4.1", | ||
"@types/node": "^17.0.25", | ||
"@typescript-eslint/eslint-plugin": "^5.20.0", | ||
"@typescript-eslint/parser": "^5.20.0", | ||
"eslint": "^8.13.0", | ||
"eslint-config-prettier": "^8.5.0", | ||
"eslint-plugin-node": "^11.1.0", | ||
"jest": "^27.5.1", | ||
"prettier": "^2.6.2", | ||
"ts-jest": "^27.1.4", | ||
"typescript": "^4.6.3" | ||
"@types/jest": "^29.5.11", | ||
"@types/node": "^20.10.6", | ||
"@typescript-eslint/eslint-plugin": "^6.17.0", | ||
"@typescript-eslint/parser": "^6.17.0", | ||
"eslint": "^8.56.0", | ||
"eslint-config-prettier": "^9.1.0", | ||
"eslint-plugin-n": "^16.6.1", | ||
"jest": "^29.7.0", | ||
"prettier": "^3.1.1", | ||
"ts-jest": "^29.1.1", | ||
"typescript": "^5.3.3" | ||
}, | ||
@@ -70,3 +70,6 @@ "engines": { | ||
"preset": "ts-jest", | ||
"testEnvironment": "node" | ||
"testEnvironment": "node", | ||
"moduleNameMapper": { | ||
"^(.*)\\.js$": "$1" | ||
} | ||
}, | ||
@@ -73,0 +76,0 @@ "prettier": { |
@@ -120,4 +120,21 @@ # bitfield | ||
--- | ||
### setAll | ||
▸ **setAll**(`array`: `ArrayLike<boolean>`, `offset?`: number): void | ||
Set the bits in the bitfield to the values in the given array. | ||
#### Parameters: | ||
| Name | Type | Default value | Description | | ||
| -------- | -------------------- | ------------- | ------------------------------------- | | ||
| `array` | `ArrayLike<boolean>` | - | Array of booleans to set the bits to. | | ||
| `offset` | number | 0 | Index of the first bit to set. | | ||
**Returns:** void | ||
## License | ||
MIT |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
31552
419
140
1