| var hpack = require('../hpack'); | 
| var utils = hpack.utils; | 
| var assert = utils.assert; | 
|   | 
| function Table(options) { | 
|   this['static'] = hpack['static-table']; | 
|   this.dynamic = []; | 
|   this.size = 0; | 
|   this.maxSize = 0; | 
|   this.length = this['static'].table.length; | 
|   this.protocolMaxSize = options.maxSize; | 
|   this.maxSize = this.protocolMaxSize; | 
|   this.lookupDepth = options.lookupDepth || 32; | 
| } | 
| module.exports = Table; | 
|   | 
| Table.create = function create(options) { | 
|   return new Table(options); | 
| }; | 
|   | 
| Table.prototype.lookup = function lookup(index) { | 
|   assert(index !== 0, 'Zero indexed field'); | 
|   assert(index <= this.length, 'Indexed field OOB') | 
|   | 
|   if (index <= this['static'].table.length) | 
|     return this['static'].table[index - 1]; | 
|   else | 
|     return this.dynamic[this.length - index]; | 
| }; | 
|   | 
| Table.prototype.reverseLookup = function reverseLookup(name, value) { | 
|   var staticEntry = this['static'].map[name]; | 
|   if (staticEntry && staticEntry.values[value]) | 
|     return staticEntry.values[value]; | 
|   | 
|   // Reverse search dynamic table (new items are at the end of it) | 
|   var limit = Math.max(0, this.dynamic.length - this.lookupDepth); | 
|   for (var i = this.dynamic.length - 1; i >= limit; i--) { | 
|     var entry = this.dynamic[i]; | 
|     if (entry.name === name && entry.value === value) | 
|       return this.length - i; | 
|   | 
|     if (entry.name === name) { | 
|       // Prefer smaller index | 
|       if (staticEntry) | 
|         break; | 
|       return -(this.length - i); | 
|     } | 
|   } | 
|   | 
|   if (staticEntry) | 
|     return -staticEntry.index; | 
|   | 
|   return 0; | 
| }; | 
|   | 
| Table.prototype.add = function add(name, value, nameSize, valueSize) { | 
|   var totalSize = nameSize + valueSize + 32; | 
|   | 
|   this.dynamic.push({ | 
|     name: name, | 
|     value: value, | 
|     nameSize: nameSize, | 
|     totalSize: totalSize | 
|   }); | 
|   this.size += totalSize; | 
|   this.length++; | 
|   | 
|   this.evict(); | 
| }; | 
|   | 
| Table.prototype.evict = function evict() { | 
|   while (this.size > this.maxSize) { | 
|     var entry = this.dynamic.shift(); | 
|     this.size -= entry.totalSize; | 
|     this.length--; | 
|   } | 
|   assert(this.size >= 0, 'Table size sanity check failed'); | 
| }; | 
|   | 
| Table.prototype.updateSize = function updateSize(size) { | 
|   assert(size <= this.protocolMaxSize, 'Table size bigger than maximum'); | 
|   this.maxSize = size; | 
|   this.evict(); | 
| }; |