function copyRawBytes(s, data, offset, length) {
    if ((s.bitOffset & 7) != 0) {
      throw "Unaligned copyBytes";
    }
    while ((s.bitOffset != 32) && (length != 0)) {
      data[offset++] = (s.accumulator32 >>> s.bitOffset);
      s.bitOffset += 8;
      length--;
    }
    if (length == 0) {
      return;
    }
    let /** @type{number} */ copyNibbles = min(halfAvailable(s), length >> 1);
    if (copyNibbles > 0) {
      let /** @type{number} */ readOffset = s.halfOffset << 1;
      let /** @type{number} */ delta = copyNibbles << 1;
      data.set(s.byteBuffer.subarray(readOffset, readOffset + delta), offset);
      offset += delta;
      length -= delta;
      s.halfOffset += copyNibbles;
    }
    if (length == 0) {
      return;
    }
    if (halfAvailable(s) > 0) {
      if (s.bitOffset >= 16) {
        s.accumulator32 = (s.shortBuffer[s.halfOffset++] << 16) | (s.accumulator32 >>> 16);
        s.bitOffset -= 16;
      }
      while (length != 0) {
        data[offset++] = (s.accumulator32 >>> s.bitOffset);
        s.bitOffset += 8;
        length--;
      }
      checkHealth(s, 0);
      return;
    }
    while (length > 0) {
      let /** @type{number} */ len = readInput(s.input, data, offset, length);
      if (len == -1) {
        throw "Unexpected end of input";
      }
      offset += len;
      length -= len;
    }
  }
@param {!State} s
@param {!Int8Array} data
@param {number} offset
@param {number} length
@return {void}