All files / src/utils qr-bit-buffer.js

97.29% Statements 72/74
100% Branches 20/20
85.71% Functions 6/7
97.29% Lines 72/74

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 757x 7x 7x 258x 7x 7x 7x 7x 7x 7x 7x 32962x 32962x 32962x 32962x 32962x 32962x 32962x 32962x 32992x 32992x 32962x 32962x 1007x 32762x 32962x 64957x 64957x 64957x 64957x 64957x 64957x 32962x 32962x 7x 7x 3731x 3731x 7x 7x     7x 7x 1318x 1318x 7x 7x 7x 7x 7x 7x 7x 4x 4x 4x 7x 7x 7x 7x 7x 200x 200x 200x 200x 1x 187x 200x 200x 1x 187x 200x 200x 7x  
export class QrBitBuffer {
  /** @type {number[]} */
  #byteBuffer = []
  #bitLength = 0
 
  /**
   * Append bit sequence to bit buffer
   * @param {number} num - bit sequence as number
   * @param {number} length - bit sequence length
   */
  put (num, length) {
    const byteBuffer = this.#byteBuffer
    const bitLength = this.#bitLength
    const newBitLength = bitLength + length
    const newBufferLength = (newBitLength + 7) >> 3
 
    let restBits = Math.min((byteBuffer.length << 3) - bitLength, length)
    let bufIndex = bitLength >> 3
    while (byteBuffer.length < newBufferLength) {
      byteBuffer.push(0)
    }
    let i = 0
    if (restBits === 0) {
      restBits = Math.min(8, length)
    }
    while (i < length) {
      const shiftLeft = bufIndex === newBufferLength - 1 ? (8 - restBits) : 0
      byteBuffer[bufIndex] |= (num << shiftLeft >>> (length - i - restBits)) & (0xff)
      i += restBits
      bufIndex++
      restBits = Math.min(8, length - i)
    }
    this.#bitLength = newBitLength
  };
 
  get byteBuffer () {
    return this.#byteBuffer.slice()
  }
 
  toByteArray () {
    return Uint8Array.from(this.#byteBuffer)
  }
 
  get bitLength () {
    return this.#bitLength
  }
 
  /**
   * Get bit value at index, value is either 0 or 1
   * @param {number} index - index position
   * @returns {number} bit value
   */
  getBitAt (index) {
    const bufIndex = index >> 3
    return (this.#byteBuffer[bufIndex] >>> (7 - index & 0b111)) & 1
  }
 
  /**
   * @param {0|1|boolean} bit bit to put
   */
  putBit (bit) {
    const byteBuffer = this.#byteBuffer
    const bitLength = this.#bitLength
    const bufIndex = bitLength >> 3
    if (byteBuffer.length <= bufIndex) {
      byteBuffer.push(0)
    }
 
    if (bit) {
      byteBuffer[bufIndex] |= (0x80 >>> (bitLength & 0b111))
    }
    this.#bitLength += 1
  }
}