128 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			128 lines
		
	
	
		
			2.9 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var hpack = require('../hpack');
 | 
						|
var utils = hpack.utils;
 | 
						|
var encoder = hpack.encoder;
 | 
						|
var table = hpack.table;
 | 
						|
var assert = utils.assert;
 | 
						|
 | 
						|
var inherits = require('inherits');
 | 
						|
var Duplex = require('readable-stream').Duplex;
 | 
						|
 | 
						|
function Compressor(options) {
 | 
						|
  Duplex.call(this, {
 | 
						|
    writableObjectMode: true
 | 
						|
  });
 | 
						|
 | 
						|
  this._encoder = null;
 | 
						|
  this._table = table.create(options.table);
 | 
						|
}
 | 
						|
inherits(Compressor, Duplex);
 | 
						|
module.exports = Compressor;
 | 
						|
 | 
						|
Compressor.create = function create(options) {
 | 
						|
  return new Compressor(options);
 | 
						|
};
 | 
						|
 | 
						|
Compressor.prototype._read = function _read() {
 | 
						|
  // We only push!
 | 
						|
};
 | 
						|
 | 
						|
Compressor.prototype._write = function _write(data, enc, cb) {
 | 
						|
  assert(Array.isArray(data), 'Compressor.write() expects list of headers');
 | 
						|
 | 
						|
  this._encoder = encoder.create();
 | 
						|
  for (var i = 0; i < data.length; i++)
 | 
						|
    this._encodeHeader(data[i]);
 | 
						|
 | 
						|
  var data = this._encoder.render();
 | 
						|
  this._encoder = null;
 | 
						|
 | 
						|
  cb(null);
 | 
						|
  for (var i = 0; i < data.length; i++)
 | 
						|
    this.push(data[i]);
 | 
						|
};
 | 
						|
 | 
						|
Compressor.prototype.updateTableSize = function updateTableSize(size) {
 | 
						|
  if (size >= this._table.protocolMaxSize) {
 | 
						|
    size = this._table.protocolMaxSize;
 | 
						|
 | 
						|
    var enc = encoder.create();
 | 
						|
 | 
						|
    // indexed = 0
 | 
						|
    // incremental = 0
 | 
						|
    // update = 1
 | 
						|
    enc.encodeBits(1, 3);
 | 
						|
    enc.encodeInt(size);
 | 
						|
 | 
						|
    var data = enc.render();
 | 
						|
    for (var i = 0; i < data.length; i++)
 | 
						|
      this.push(data[i]);
 | 
						|
  }
 | 
						|
 | 
						|
  this._table.updateSize(size);
 | 
						|
};
 | 
						|
 | 
						|
Compressor.prototype.reset = function reset() {
 | 
						|
  var enc = encoder.create();
 | 
						|
  var size = this._table.maxSize;
 | 
						|
 | 
						|
  // indexed = 0
 | 
						|
  // incremental = 0
 | 
						|
  // update = 1
 | 
						|
  enc.encodeBits(1, 3);
 | 
						|
  enc.encodeInt(0);
 | 
						|
 | 
						|
  // Evict everything
 | 
						|
  this._table.updateSize(0);
 | 
						|
 | 
						|
  // indexed = 0
 | 
						|
  // incremental = 0
 | 
						|
  // update = 1
 | 
						|
  enc.encodeBits(1, 3);
 | 
						|
  enc.encodeInt(size);
 | 
						|
 | 
						|
  // Revert size
 | 
						|
  this._table.updateSize(size);
 | 
						|
 | 
						|
  var data = enc.render();
 | 
						|
  for (var i = 0; i < data.length; i++)
 | 
						|
    this.push(data[i]);
 | 
						|
};
 | 
						|
 | 
						|
Compressor.prototype._encodeHeader = function _encodeHeader(header) {
 | 
						|
  if (header.neverIndex) {
 | 
						|
    var index = 0;
 | 
						|
    var neverIndex = 1;
 | 
						|
    var isIndexed = 0;
 | 
						|
    var isIncremental = 0;
 | 
						|
  } else {
 | 
						|
    var index = this._table.reverseLookup(header.name, header.value);
 | 
						|
    var isIndexed = index > 0;
 | 
						|
    var isIncremental = header.incremental !== false;
 | 
						|
    var neverIndex = 0;
 | 
						|
  }
 | 
						|
 | 
						|
  this._encoder.encodeBit(isIndexed);
 | 
						|
  if (isIndexed) {
 | 
						|
    this._encoder.encodeInt(index);
 | 
						|
    return;
 | 
						|
  }
 | 
						|
 | 
						|
  var name = utils.toArray(header.name);
 | 
						|
  var value = utils.toArray(header.value);
 | 
						|
 | 
						|
  this._encoder.encodeBit(isIncremental);
 | 
						|
  if (isIncremental) {
 | 
						|
    this._table.add(header.name, header.value, name.length, value.length);
 | 
						|
  } else {
 | 
						|
    // Update = false
 | 
						|
    this._encoder.encodeBit(0);
 | 
						|
    this._encoder.encodeBit(neverIndex);
 | 
						|
  }
 | 
						|
 | 
						|
  // index is negative for `name`-only headers
 | 
						|
  this._encoder.encodeInt(-index);
 | 
						|
  if (index === 0)
 | 
						|
    this._encoder.encodeStr(name, header.huffman !== false);
 | 
						|
  this._encoder.encodeStr(value, header.huffman !== false);
 | 
						|
};
 |