117 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			117 lines
		
	
	
		
			2.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
var hpack = require('../hpack');
 | 
						|
var utils = hpack.utils;
 | 
						|
var decoder = hpack.decoder;
 | 
						|
var table = hpack.table;
 | 
						|
var assert = utils.assert;
 | 
						|
 | 
						|
var inherits = require('inherits');
 | 
						|
var Duplex = require('readable-stream').Duplex;
 | 
						|
 | 
						|
function Decompressor(options) {
 | 
						|
  Duplex.call(this, {
 | 
						|
    readableObjectMode: true
 | 
						|
  });
 | 
						|
 | 
						|
  this._decoder = decoder.create();
 | 
						|
  this._table = table.create(options.table);
 | 
						|
}
 | 
						|
inherits(Decompressor, Duplex);
 | 
						|
module.exports = Decompressor;
 | 
						|
 | 
						|
Decompressor.create = function create(options) {
 | 
						|
  return new Decompressor(options);
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._read = function _read() {
 | 
						|
  // We only push!
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._write = function _write(data, enc, cb) {
 | 
						|
  this._decoder.push(data);
 | 
						|
 | 
						|
  cb(null);
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype.execute = function execute(cb) {
 | 
						|
  while (!this._decoder.isEmpty()) {
 | 
						|
    try {
 | 
						|
      this._execute();
 | 
						|
    } catch (err) {
 | 
						|
      if (cb)
 | 
						|
        return done(err);
 | 
						|
      else
 | 
						|
        return this.emit('error', err);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (cb)
 | 
						|
    done(null);
 | 
						|
 | 
						|
  function done(err) {
 | 
						|
    process.nextTick(function() {
 | 
						|
      cb(err);
 | 
						|
    });
 | 
						|
  }
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype.updateTableSize = function updateTableSize(size) {
 | 
						|
  this._table.updateSize(size);
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._execute = function _execute() {
 | 
						|
  var isIndexed = this._decoder.decodeBit();
 | 
						|
  if (isIndexed)
 | 
						|
    return this._processIndexed();
 | 
						|
 | 
						|
  var isIncremental = this._decoder.decodeBit();
 | 
						|
  var neverIndex = 0;
 | 
						|
  if (!isIncremental) {
 | 
						|
    var isUpdate = this._decoder.decodeBit();
 | 
						|
    if (isUpdate)
 | 
						|
      return this._processUpdate();
 | 
						|
 | 
						|
    neverIndex = this._decoder.decodeBit();
 | 
						|
  }
 | 
						|
 | 
						|
  this._processLiteral(isIncremental, neverIndex);
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._processIndexed = function _processIndexed() {
 | 
						|
  var index = this._decoder.decodeInt();
 | 
						|
 | 
						|
  var lookup = this._table.lookup(index);
 | 
						|
  this.push({ name: lookup.name, value: lookup.value, neverIndex: false });
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._processLiteral = function _processLiteral(inc, never) {
 | 
						|
  var index = this._decoder.decodeInt();
 | 
						|
 | 
						|
  var name;
 | 
						|
  var nameSize;
 | 
						|
 | 
						|
  // Literal header-name too
 | 
						|
  if (index === 0) {
 | 
						|
    name = this._decoder.decodeStr();
 | 
						|
    nameSize = name.length;
 | 
						|
    name = utils.stringify(name);
 | 
						|
  } else {
 | 
						|
    var lookup = this._table.lookup(index);
 | 
						|
    nameSize = lookup.nameSize;
 | 
						|
    name = lookup.name;
 | 
						|
  }
 | 
						|
 | 
						|
  var value = this._decoder.decodeStr();
 | 
						|
  var valueSize = value.length;
 | 
						|
  value = utils.stringify(value);
 | 
						|
 | 
						|
  if (inc)
 | 
						|
    this._table.add(name, value, nameSize, valueSize);
 | 
						|
 | 
						|
  this.push({ name: name, value: value, neverIndex: never !== 0});
 | 
						|
};
 | 
						|
 | 
						|
Decompressor.prototype._processUpdate = function _processUpdate() {
 | 
						|
  var size = this._decoder.decodeInt();
 | 
						|
  this.updateTableSize(size);
 | 
						|
};
 |