UNPKG

quic

Version:

A QUIC server/client implementation in Node.js.

216 lines 6.35 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); // **Github:** https://github.com/fidm/quic // // **License:** MIT const util_1 = require("util"); const dns_1 = require("dns"); exports.lookup = util_1.promisify(dns_1.lookup); class Visitor { constructor(start = 0, end = 0) { this.start = start; this.end = end > start ? end : start; } reset(start = 0, end = 0) { this.start = start; if (end >= this.start) { this.end = end; } else if (this.end < this.start) { this.end = this.start; } return this; } walk(steps) { this.start = this.end; this.end += steps; return this; } } exports.Visitor = Visitor; class BufferVisitor extends Visitor { constructor(buf, start = 0, end = 0) { super(start, end); this.buf = buf; } get length() { return this.buf.length; } isOutside() { return this.end > this.buf.length; } } exports.BufferVisitor = BufferVisitor; function toBuffer(obj) { const bufv = obj.writeTo(new BufferVisitor(Buffer.alloc(obj.byteLen()))); return bufv.buf; } exports.toBuffer = toBuffer; // We define an unsigned 16-bit floating point value, inspired by IEEE floats // (http://en.wikipedia.org/wiki/Half_precision_floating-point_format), // with 5-bit exponent (bias 1), 11-bit mantissa (effective 12 with hidden // bit) and denormals, but without signs, transfinites or fractions. Wire format // 16 bits (little-endian byte order) are split into exponent (high 5) and // mantissa (low 11) // https://github.com/google/proto-quic/blob/master/src/net/quic/core/quic_protocol.h#L197 const Float16ExponentBits = 5; const Float16MantissaBits = 16 - Float16ExponentBits; // 11 const Float16MantissaEffectiveBits = Float16MantissaBits + 1; // 12 const Float16MantissaEffectiveValue = 1 << Float16MantissaEffectiveBits; // Float16MaxValue === readUFloat16(<Buffer 0xff 0xff>) exports.Float16MaxValue = 0x3FFC0000000; function readUFloat16(buf, offset = 0) { let value = buf.readUInt16BE(offset); if (value < Float16MantissaEffectiveValue) { return value; } let exponent = value >> Float16MantissaBits; --exponent; value -= exponent << Float16MantissaBits; // we can only use binary bitwise operators in 32 bits const res = value * Math.pow(2, exponent); return res < exports.Float16MaxValue ? res : exports.Float16MaxValue; } exports.readUFloat16 = readUFloat16; function writeUFloat16(buf, value, offset) { let res = 0; if (value < Float16MantissaEffectiveValue) { res = value; } else if (value >= exports.Float16MaxValue) { res = 0xffff; } else { let exponent = 0; for (let i = 16; i >= 1; i /= 2) { if (value >= (1 << (Float16MantissaBits + i))) { exponent += i; value /= Math.pow(2, i); } } res = Math.floor(value) + (exponent << Float16MantissaBits); } buf.writeUInt16BE(res, offset); return buf; } exports.writeUFloat16 = writeUFloat16; const unsafeUIntRadix = 0xffffffffffff + 1; function readUnsafeUInt(buf, offset, len) { let val = 0; if (len > 6) { val = buf.readUIntBE(offset + len - 6, 6); const high = buf.readUIntBE(offset, len - 6); if (high > 0) { val += high * unsafeUIntRadix; } } else if (len > 0) { val = buf.readUIntBE(offset, len); } return val; } exports.readUnsafeUInt = readUnsafeUInt; function writeUnsafeUInt(buf, val, offset, len) { if (len > 6) { if (val <= 0xffffffffffff) { buf.writeUIntBE(val, offset + len - 6, 6); buf.writeUIntBE(0, offset, len - 6); // clear cached bits } else { const high = Math.floor(val / unsafeUIntRadix); buf.writeUIntBE(val - high * unsafeUIntRadix, offset + len - 6, 6); buf.writeUIntBE(high, offset, len - 6); } } else if (len > 0) { buf.writeUIntBE(val, offset, len); } return buf; } exports.writeUnsafeUInt = writeUnsafeUInt; class Queue { constructor() { this.tail = []; this.head = []; this.offset = 0; this.hLength = 0; } get length() { return this.hLength + this.tail.length - this.offset; } first() { return this.hLength === this.offset ? this.tail[0] : this.head[this.offset]; } push(item) { this.tail.push(item); } pop() { if (this.tail.length > 0) { return this.tail.pop(); } if (this.hLength === 0) { return; } this.hLength--; return this.head.pop(); } unshift(item) { if (this.offset === 0) { this.hLength++; this.head.unshift(item); } else { this.offset--; this.head[this.offset] = item; } } shift() { if (this.offset === this.hLength) { if (this.tail.length === 0) { return; } const tmp = this.head; tmp.length = 0; this.head = this.tail; this.tail = tmp; this.offset = 0; this.hLength = this.head.length; } return this.head[this.offset++]; } toArray() { const arr = []; if (this.offset === this.hLength) { for (const item of this.tail) { arr.push(item); } } else { for (let i = this.offset, l = this.head.length; i < l; i++) { arr.push(this.head[i]); } } return arr; } reset() { this.offset = 0; this.hLength = 0; this.tail.length = 0; this.head.length = 0; } migrateTo(queue) { let i = this.offset; const len = this.tail.length; while (i < this.hLength) { queue.push(this.head[i++]); } i = 0; while (i < len) { queue.push(this.tail[i++]); } this.offset = this.hLength = this.head.length = this.tail.length = 0; return queue; } } exports.Queue = Queue; //# sourceMappingURL=common.js.map