big-bitfield
Version:
library for storing a bitfield with a large number of options stored as an array/buffer, suitable for e.g. permissions systems
73 lines (59 loc) • 1.76 kB
JavaScript
'use strict';
const DEFAULT_SIZE = 8;
class BitField {
#array;
// data number for number of bits or base64 representation of array
constructor(data = DEFAULT_SIZE) {
const arrayFrom = typeof data === 'number'
? data
: Buffer.from(data, 'base64');
this.#array = new Uint8Array(arrayFrom);
}
// return boolean for state of a bit, always false if larger than the length
get(bit) {
const i = bit >> 3;
if (i >= this.#array.length) {
console.warn('big-bitfield attempted to get bit', bit, 'which is more than the array size', this.#array.length, 'can store. This always returns false.');
return false;
}
return (this.#array[i] & 128 >> bit % 8) === 128 >> bit % 8;
}
// set a bit, default true if not specified, noop if larger than size
set(bit, value = true) {
const i = bit >> 3;
if (i < this.#array.length) {
if (value === true) {
this.#array[i] |= (128 >> bit % 8);
} else {
this.#array[i] &= ~(128 >> bit % 8);
}
} else {
console.warn('big-bitfield attempted to set bit', bit, 'which is more than the array size', this.#array.length, 'can store. This is a noop.');
}
}
// set all bits from an array
setAll(bits = [], value = true) {
bits.forEach(bit => this.set(bit, value));
}
// return boolean for if ALL bits given in arguments spread are true
hasAll(...bits) {
return !bits
.some(b => this.get(b) !== true);
}
// return boolean for if ANY bits given in arguments spread are true
hasAny(...bits) {
return bits
.some(b => this.get(b) === true);
}
// return the internal array
get array() {
return this.#array;
}
// return base64 representation
get base64() {
return Buffer
.from(this.#array)
.toString('base64');
}
}
module.exports = BitField;