UNPKG

@nuintun/qrcode

Version:

A pure JavaScript QRCode encode and decode library.

101 lines (96 loc) 2.37 kB
/** * @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 */ 'use strict'; const utils = require('./utils.cjs'); /** * @module BitArray */ const LOAD_FACTOR = 0.75; function offset(index) { return utils.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)] |= utils.getBitMask(index); } get(index) { return utils.toBit(this.#bits[offset(index)] >>> utils.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 (utils.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); } } exports.BitArray = BitArray;