You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
116 lines
2.6 KiB
116 lines
2.6 KiB
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); |
|
};
|
|
|