@nuintun/qrcode
Version:
A pure JavaScript QRCode encode and decode library.
99 lines (95 loc) • 2.35 kB
JavaScript
/**
* @module QRCode
* @package @nuintun/qrcode
* @license MIT
* @version 5.0.2
* @author nuintun <nuintun@qq.com>
* @description A pure JavaScript QRCode encode and decode library.
* @see https://github.com/nuintun/qrcode#readme
*/
import { getBitMask, toBit, getBitOffset, toInt32 } from './utils.js';
/**
* @module BitArray
*/
const LOAD_FACTOR = 0.75;
function offset(index) {
return toInt32(index / 32);
}
function makeArray(length) {
return new Int32Array(Math.ceil(length / 32));
}
class BitArray {
#length;
#bits;
constructor(length = 0) {
this.#length = length;
this.#bits = makeArray(length);
}
#alloc(length) {
const bits = this.#bits;
if (length > bits.length * 32) {
const array = makeArray(Math.ceil(length / LOAD_FACTOR));
array.set(bits);
this.#bits = array;
}
this.#length = length;
}
get length() {
return this.#length;
}
get byteLength() {
return Math.ceil(this.#length / 8);
}
set(index) {
this.#bits[offset(index)] |= getBitMask(index);
}
get(index) {
return toBit(this.#bits[offset(index)] >>> getBitOffset(index));
}
xor(mask) {
const bits = this.#bits;
const maskBits = mask.#bits;
const length = Math.min(this.#length, mask.#length);
for (let i = 0; i < length; i++) {
// The last int could be incomplete (i.e. not have 32 bits in
// it) but there is no problem since 0 XOR 0 == 0.
bits[i] ^= maskBits[i];
}
}
append(value, length = 1) {
let index = this.#length;
if (value instanceof BitArray) {
length = value.#length;
this.#alloc(index + length);
for (let i = 0; i < length; i++) {
if (value.get(i) !== 0) {
this.set(index);
}
index++;
}
} else {
this.#alloc(index + length);
for (let i = length - 1; i >= 0; i--) {
if (toBit(value >>> i) !== 0) {
this.set(index);
}
index++;
}
}
}
writeToUint8Array(bitOffset, target, byteOffset, byteLength) {
for (let i = 0; i < byteLength; i++) {
let byte = 0;
for (let j = 0; j < 8; j++) {
if (this.get(bitOffset++) !== 0) {
byte |= 1 << (7 - j);
}
}
target[byteOffset + i] = byte;
}
}
clear() {
this.#bits.fill(0);
}
}
export { BitArray };