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 23x 23x 23x 23x 23x 23x 23x 23x 23x 23x 267x 267x 267x 267x 267x 267x 267x 267x 297x 297x 267x 267x 67x 67x 267x 497x 497x 497x 497x 497x 497x 267x 267x 23x 23x 146x 146x 23x 23x     23x 23x 87x 87x 23x 23x 23x 23x 23x 23x 23x 4x 4x 4x 23x 23x 23x 23x 23x 14x 14x 14x 14x 1x 1x 14x 14x 1x 1x 14x 14x 23x  
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
  }
}