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

97.29% Statements 72/74
100% Branches 13/13
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 751x 1x 1x 23x 1x 1x 1x 1x 1x 1x 1x 267x 267x 267x 267x 267x 267x 267x 267x 297x 297x 267x 267x 67x 67x 267x 497x 497x 497x 497x 497x 497x 267x 267x 1x 1x 146x 146x 1x 1x     1x 1x 87x 87x 1x 1x 1x 1x 1x 1x 1x 4x 4x 4x 1x 1x 1x 1x 1x 14x 14x 14x 14x 1x 1x 14x 14x 1x 1x 14x 14x 1x  
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
  }
}