| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129 | var hpack = require('../hpack');var utils = hpack.utils;var huffman = hpack.huffman.encode;var assert = utils.assert;var WBuf = require('wbuf');function Encoder() {  this.buffer = new WBuf();  this.word = 0;  this.bitOffset = 0;}module.exports = Encoder;Encoder.create = function create() {  return new Encoder();};Encoder.prototype.render = function render() {  return this.buffer.render();};Encoder.prototype.encodeBit = function encodeBit(bit) {  var octet;  this.word <<= 1;  this.word |= bit;  this.bitOffset++;  if (this.bitOffset === 8) {    this.buffer.writeUInt8(this.word);    this.word = 0;    this.bitOffset = 0;  }};Encoder.prototype.encodeBits = function encodeBits(bits, len) {  var left = bits;  var leftLen = len;  while (leftLen > 0) {    var avail = Math.min(leftLen, 8 - this.bitOffset);    var toWrite = left >>> (leftLen - avail);    if (avail === 8) {      this.buffer.writeUInt8(toWrite);    } else {      this.word <<= avail;      this.word |= toWrite;      this.bitOffset += avail;      if (this.bitOffset === 8) {        this.buffer.writeUInt8(this.word);        this.word = 0;        this.bitOffset = 0;      }    }    leftLen -= avail;    left &= (1 << leftLen) - 1;  }};// Just for testingEncoder.prototype.skipBits = function skipBits(num) {  this.bitOffset += num;  this.buffer.skip(this.bitOffset >> 3);  this.bitOffset &= 0x7;};Encoder.prototype.encodeInt = function encodeInt(num) {  var prefix = 8 - this.bitOffset;  // We are going to end up octet-aligned  this.bitOffset = 0;  var max = (1 << prefix) - 1;  // Fast case - int fits into the prefix  if (num < max) {    this.buffer.writeUInt8((this.word << prefix) | num);    return octet;  }  var left = num - max;  this.buffer.writeUInt8((this.word << prefix) | max);  do {    var octet = left & 0x7f;    left >>= 7;    if (left !== 0)      octet |= 0x80;    this.buffer.writeUInt8(octet);  } while (left !== 0);};Encoder.prototype.encodeStr = function encodeStr(value, isHuffman) {  this.encodeBit(isHuffman ? 1 : 0);  if (!isHuffman) {    this.buffer.reserve(value.length + 1);    this.encodeInt(value.length);    for (var i = 0; i < value.length; i++)      this.buffer.writeUInt8(value[i]);    return;  }  var codes = [];  var len = 0;  var pad = 0;  for (var i = 0; i < value.length; i++) {    var code = huffman[value[i]];    codes.push(code);    len += code[0];  }  if (len % 8 !== 0)    pad = 8 - (len % 8);  len += pad;  this.buffer.reserve((len / 8) + 1);  this.encodeInt(len / 8);  for (var i = 0; i < codes.length; i++) {    var code = codes[i];    this.encodeBits(code[1], code[0]);  }  // Append padding  this.encodeBits(0xff >>> (8 - pad), pad);};
 |