249 lines
29 KiB
JavaScript
249 lines
29 KiB
JavaScript
|
|
"use strict";
|
||
|
|
|
||
|
|
Object.defineProperty(exports, "__esModule", {
|
||
|
|
value: true
|
||
|
|
});
|
||
|
|
exports.default = void 0;
|
||
|
|
const SHIFT_LEFT_32 = (1 << 16) * (1 << 16);
|
||
|
|
const SHIFT_RIGHT_32 = 1 / SHIFT_LEFT_32;
|
||
|
|
const UNKNOWN_PLP_LEN = Buffer.from([0xfe, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff]);
|
||
|
|
const ZERO_LENGTH_BUFFER = Buffer.alloc(0);
|
||
|
|
/**
|
||
|
|
A Buffer-like class that tracks position.
|
||
|
|
|
||
|
|
As values are written, the position advances by the size of the written data.
|
||
|
|
When writing, automatically allocates new buffers if there's not enough space.
|
||
|
|
*/
|
||
|
|
class WritableTrackingBuffer {
|
||
|
|
constructor(initialSize, encoding, doubleSizeGrowth) {
|
||
|
|
this.initialSize = initialSize;
|
||
|
|
this.encoding = encoding || 'ucs2';
|
||
|
|
this.doubleSizeGrowth = doubleSizeGrowth || false;
|
||
|
|
this.buffer = Buffer.alloc(this.initialSize, 0);
|
||
|
|
this.compositeBuffer = ZERO_LENGTH_BUFFER;
|
||
|
|
this.position = 0;
|
||
|
|
}
|
||
|
|
get data() {
|
||
|
|
this.newBuffer(0);
|
||
|
|
return this.compositeBuffer;
|
||
|
|
}
|
||
|
|
copyFrom(buffer) {
|
||
|
|
const length = buffer.length;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
buffer.copy(this.buffer, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
makeRoomFor(requiredLength) {
|
||
|
|
if (this.buffer.length - this.position < requiredLength) {
|
||
|
|
if (this.doubleSizeGrowth) {
|
||
|
|
let size = Math.max(128, this.buffer.length * 2);
|
||
|
|
while (size < requiredLength) {
|
||
|
|
size *= 2;
|
||
|
|
}
|
||
|
|
this.newBuffer(size);
|
||
|
|
} else {
|
||
|
|
this.newBuffer(requiredLength);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
newBuffer(size) {
|
||
|
|
const buffer = this.buffer.slice(0, this.position);
|
||
|
|
this.compositeBuffer = Buffer.concat([this.compositeBuffer, buffer]);
|
||
|
|
this.buffer = size === 0 ? ZERO_LENGTH_BUFFER : Buffer.alloc(size, 0);
|
||
|
|
this.position = 0;
|
||
|
|
}
|
||
|
|
writeUInt8(value) {
|
||
|
|
const length = 1;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeUInt8(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUInt16LE(value) {
|
||
|
|
const length = 2;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeUInt16LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUShort(value) {
|
||
|
|
this.writeUInt16LE(value);
|
||
|
|
}
|
||
|
|
writeUInt16BE(value) {
|
||
|
|
const length = 2;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeUInt16BE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUInt24LE(value) {
|
||
|
|
const length = 3;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer[this.position + 2] = value >>> 16 & 0xff;
|
||
|
|
this.buffer[this.position + 1] = value >>> 8 & 0xff;
|
||
|
|
this.buffer[this.position] = value & 0xff;
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUInt32LE(value) {
|
||
|
|
const length = 4;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeUInt32LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeBigInt64LE(value) {
|
||
|
|
const length = 8;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeBigInt64LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeInt64LE(value) {
|
||
|
|
this.writeBigInt64LE(BigInt(value));
|
||
|
|
}
|
||
|
|
writeUInt64LE(value) {
|
||
|
|
this.writeBigUInt64LE(BigInt(value));
|
||
|
|
}
|
||
|
|
writeBigUInt64LE(value) {
|
||
|
|
const length = 8;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeBigUInt64LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUInt32BE(value) {
|
||
|
|
const length = 4;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeUInt32BE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeUInt40LE(value) {
|
||
|
|
// inspired by https://github.com/dpw/node-buffer-more-ints
|
||
|
|
this.writeInt32LE(value & -1);
|
||
|
|
this.writeUInt8(Math.floor(value * SHIFT_RIGHT_32));
|
||
|
|
}
|
||
|
|
writeInt8(value) {
|
||
|
|
const length = 1;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeInt8(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeInt16LE(value) {
|
||
|
|
const length = 2;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeInt16LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeInt16BE(value) {
|
||
|
|
const length = 2;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeInt16BE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeInt32LE(value) {
|
||
|
|
const length = 4;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeInt32LE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeInt32BE(value) {
|
||
|
|
const length = 4;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeInt32BE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeFloatLE(value) {
|
||
|
|
const length = 4;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeFloatLE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeDoubleLE(value) {
|
||
|
|
const length = 8;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.writeDoubleLE(value, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeString(value, encoding) {
|
||
|
|
if (encoding == null) {
|
||
|
|
encoding = this.encoding;
|
||
|
|
}
|
||
|
|
const length = Buffer.byteLength(value, encoding);
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
|
||
|
|
// $FlowFixMe https://github.com/facebook/flow/pull/5398
|
||
|
|
this.buffer.write(value, this.position, encoding);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeBVarchar(value, encoding) {
|
||
|
|
this.writeUInt8(value.length);
|
||
|
|
this.writeString(value, encoding);
|
||
|
|
}
|
||
|
|
writeUsVarchar(value, encoding) {
|
||
|
|
this.writeUInt16LE(value.length);
|
||
|
|
this.writeString(value, encoding);
|
||
|
|
}
|
||
|
|
|
||
|
|
// TODO: Figure out what types are passed in other than `Buffer`
|
||
|
|
writeUsVarbyte(value, encoding) {
|
||
|
|
if (encoding == null) {
|
||
|
|
encoding = this.encoding;
|
||
|
|
}
|
||
|
|
let length;
|
||
|
|
if (value instanceof Buffer) {
|
||
|
|
length = value.length;
|
||
|
|
} else {
|
||
|
|
value = value.toString();
|
||
|
|
length = Buffer.byteLength(value, encoding);
|
||
|
|
}
|
||
|
|
this.writeUInt16LE(length);
|
||
|
|
if (value instanceof Buffer) {
|
||
|
|
this.writeBuffer(value);
|
||
|
|
} else {
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
// $FlowFixMe https://github.com/facebook/flow/pull/5398
|
||
|
|
this.buffer.write(value, this.position, encoding);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
writePLPBody(value, encoding) {
|
||
|
|
if (encoding == null) {
|
||
|
|
encoding = this.encoding;
|
||
|
|
}
|
||
|
|
let length;
|
||
|
|
if (value instanceof Buffer) {
|
||
|
|
length = value.length;
|
||
|
|
} else {
|
||
|
|
value = value.toString();
|
||
|
|
length = Buffer.byteLength(value, encoding);
|
||
|
|
}
|
||
|
|
|
||
|
|
// Length of all chunks.
|
||
|
|
// this.writeUInt64LE(length);
|
||
|
|
// unknown seems to work better here - might revisit later.
|
||
|
|
this.writeBuffer(UNKNOWN_PLP_LEN);
|
||
|
|
|
||
|
|
// In the UNKNOWN_PLP_LEN case, the data is represented as a series of zero or more chunks.
|
||
|
|
if (length > 0) {
|
||
|
|
// One chunk.
|
||
|
|
this.writeUInt32LE(length);
|
||
|
|
if (value instanceof Buffer) {
|
||
|
|
this.writeBuffer(value);
|
||
|
|
} else {
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
this.buffer.write(value, this.position, encoding);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
// PLP_TERMINATOR (no more chunks).
|
||
|
|
this.writeUInt32LE(0);
|
||
|
|
}
|
||
|
|
writeBuffer(value) {
|
||
|
|
const length = value.length;
|
||
|
|
this.makeRoomFor(length);
|
||
|
|
value.copy(this.buffer, this.position);
|
||
|
|
this.position += length;
|
||
|
|
}
|
||
|
|
writeMoney(value) {
|
||
|
|
this.writeInt32LE(Math.floor(value * SHIFT_RIGHT_32));
|
||
|
|
this.writeInt32LE(value & -1);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
var _default = exports.default = WritableTrackingBuffer;
|
||
|
|
module.exports = WritableTrackingBuffer;
|
||
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJTSElGVF9MRUZUXzMyIiwiU0hJRlRfUklHSFRfMzIiLCJVTktOT1dOX1BMUF9MRU4iLCJCdWZmZXIiLCJmcm9tIiwiWkVST19MRU5HVEhfQlVGRkVSIiwiYWxsb2MiLCJXcml0YWJsZVRyYWNraW5nQnVmZmVyIiwiY29uc3RydWN0b3IiLCJpbml0aWFsU2l6ZSIsImVuY29kaW5nIiwiZG91YmxlU2l6ZUdyb3d0aCIsImJ1ZmZlciIsImNvbXBvc2l0ZUJ1ZmZlciIsInBvc2l0aW9uIiwiZGF0YSIsIm5ld0J1ZmZlciIsImNvcHlGcm9tIiwibGVuZ3RoIiwibWFrZVJvb21Gb3IiLCJjb3B5IiwicmVxdWlyZWRMZW5ndGgiLCJzaXplIiwiTWF0aCIsIm1heCIsInNsaWNlIiwiY29uY2F0Iiwid3JpdGVVSW50OCIsInZhbHVlIiwid3JpdGVVSW50MTZMRSIsIndyaXRlVVNob3J0Iiwid3JpdGVVSW50MTZCRSIsIndyaXRlVUludDI0TEUiLCJ3cml0ZVVJbnQzMkxFIiwid3JpdGVCaWdJbnQ2NExFIiwid3JpdGVJbnQ2NExFIiwiQmlnSW50Iiwid3JpdGVVSW50NjRMRSIsIndyaXRlQmlnVUludDY0TEUiLCJ3cml0ZVVJbnQzMkJFIiwid3JpdGVVSW50NDBMRSIsIndyaXRlSW50MzJMRSIsImZsb29yIiwid3JpdGVJbnQ4Iiwid3JpdGVJbnQxNkxFIiwid3JpdGVJbnQxNkJFIiwid3JpdGVJbnQzMkJFIiwid3JpdGVGbG9hdExFIiwid3JpdGVEb3VibGVMRSIsIndyaXRlU3RyaW5nIiwiYnl0ZUxlbmd0aCIsIndyaXRlIiwid3JpdGVCVmFyY2hhciIsIndyaXRlVXNWYXJjaGFyIiwid3JpdGVVc1ZhcmJ5dGUiLCJ0b1N0cmluZyIsIndyaXRlQnVmZmVyIiwid3JpdGVQTFBCb2R5Iiwid3JpdGVNb25leSIsIl9kZWZhdWx0IiwiZXhwb3J0cyIsImRlZmF1bHQiLCJtb2R1bGUiXSwic291cmNlcyI6WyIuLi8uLi9zcmMvdHJhY2tpbmctYnVmZmVyL3dyaXRhYmxlLXRyYWNraW5nLWJ1ZmZlci50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJjb25zdCBTSElGVF9MRUZUXzMyID0gKDEgPDwgMTYpICogKDEgPDwgMTYpO1xuY29uc3QgU0hJRlRfUklHSFRfMzIgPSAxIC8gU0hJRlRfTEVGVF8zMjtcbmNvbnN0IFVOS05PV05fUExQX0xFTiA9IEJ1ZmZlci5mcm9tKFsweGZlLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmLCAweGZmXSk7XG5jb25zdCBaRVJPX0xFTkdUSF9CVUZGRVIgPSBCdWZmZXIuYWxsb2MoMCk7XG5cbmV4cG9ydCB0eXBlIEVuY29kaW5nID0gJ3V0ZjgnIHwgJ3VjczInIHwgJ2FzY2lpJztcblxuLyoqXG4gIEEgQnVmZmVyLWxpa2UgY2xhc3MgdGhhdCB0cmFja3MgcG9zaXRpb24uXG5cbiAgQXMgdmFsdWVzIGFyZSB3cml0dGVuLCB0aGUgcG9zaXRpb24gYWR2YW5jZXMgYnkgdGhlIHNpemUgb2YgdGhlIHdyaXR0ZW4gZGF0YS5cbiAgV2hlbiB3cml0aW5nLCBhdXRvbWF0aWNhbGx5IGFsbG9jYXRlcyBuZXcgYnVmZmVycyBpZiB0aGVyZSdzIG5vdCBlbm91Z2ggc3BhY2UuXG4gKi9cbmNsYXNzIFdyaXRhYmxlVHJhY2tpbmdCdWZmZXIge1xuICBkZWNsYXJlIGluaXRpYWxTaXplOiBudW1iZXI7XG4gIGRlY2xhcmUgZW5jb2Rpbmc6IEVuY29kaW5nO1xuICBkZWNsYXJlIGRvdWJsZVNpemVHcm93dGg6IGJvb2xlYW47XG5cbiAgZGVjbGFyZSBidWZmZXI6IEJ1ZmZlcjtcbiAgZGVjbGFyZSBjb21wb3NpdGVCdWZmZXI6IEJ1ZmZlcjtcblxuICBkZWNsYXJlIHBvc2l0aW9uOiBudW1iZXI7XG5cbiAgY29uc3RydWN0b3IoaW5pdGlhbFNpemU6IG51bWJlciwgZW5jb2Rpbmc/OiBFbmNvZGluZyB8IG51bGwsIGRvdWJsZVNpemVHcm93dGg/OiBib29sZWFuKSB7XG4gICAgdGhpcy5pbml0aWFsU2l6ZSA9IGluaXRpYWxTaXplO1xuICAgIHRoaXMuZW5jb2RpbmcgPSBlbmNvZGluZyB8fCAndWNzMic7XG4gICAgdGhpcy5kb3VibGVTaXplR3Jvd3RoID0gZG91YmxlU2l6ZUdyb3d0aCB8fCBmYWxzZTtcbiAgICB0aGlzLmJ1ZmZlciA9IEJ1ZmZlci5hbGxvYyh0aGlzLmluaXRpYWxTaXplLCAwKTtcbiAgICB0aGlzLmNvbXBvc2l0ZUJ1ZmZlciA9IFpFUk9fTEVOR1RIX0JVRkZFUjtcbiAgICB0aGlzLnBvc2l0aW9uID0gMDtcbiAgfVxuXG4gIGdldCBkYXRhKCkge1xuICAgIHRoaXMubmV3QnVmZmVyKDApO1xuICAgIHJldHVybiB0aGlzLmNvbXBvc2l0ZUJ1ZmZlcjtcbiAgfVxuXG4gIGNvcHlGcm9tKGJ1ZmZlcjogQnVmZmVyKSB7XG4gICAgY29uc3QgbGVuZ3RoID0gYnVmZmVyLmxlbmd0aDtcbiAgICB0aGlzLm1ha2VSb29tRm9yKGxlbmd0aCk7XG4gICAgYnVmZmVyLmNvcHkodGhpcy5idWZmZXIsIHRoaXMucG9zaXRpb24pO1xuICAgIHRoaXMucG9zaXRpb24gKz0gbGVuZ3RoO1xuICB9XG5cbiAgbWFrZVJvb21Gb3IocmVxdWlyZWRMZW5ndGg6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmJ1ZmZlci5sZW5ndGggLSB0aGlzLnBvc2l0aW9uIDwgcmVxdWlyZWRMZW5ndGgpIHtcbiAgICAgIGlmICh0aGlzLmRvdWJsZVNpemVHcm93dGgpIHtcbiAgICAgICAgbGV0IHNpemUgPSBNYXRoLm1heCgxMjgsIHRoaXMuYnVmZmVyLmxlbmd0aCAqIDIpO1xuICAgICAgICB3aGlsZSAoc2l6ZSA8IHJlcXVpcmVkTGVuZ3RoKSB7XG4gICAgICAgICAgc2l6ZSAqPSAyO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMubmV3QnVmZmVyKHNpemUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5uZXdCdWZmZXIocmVxdWlyZWRMZW5ndGgpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIG5ld0J1ZmZlcihzaXplOiBudW1iZXIpIHtcbiAgICBjb25zdCBidWZmZXIgPSB0aGlzLmJ1ZmZlci5zbGljZSgwLCB0aGlzLnBvc2l0aW9uKTtcbiAgICB0aGlzLmNvbXBvc2l0ZUJ1ZmZlciA9IEJ1ZmZlci5jb25jYXQoW3RoaXMuY29tcG9zaXRlQnVmZmVyLCBidWZmZXJdKTtcbiAgICB0aGlzLmJ1ZmZlciA9IChzaXplID09PSAwKSA/IFpFUk9fTEVOR1RIX0JVRkZFUiA6IEJ1ZmZlci5hbGxvYyhzaXplLCAwKTtcbiAgICB0aGlzLnBvc2l0aW9uID0gMDtcbiAgfVxuXG4gIHdyaXRlVUludDgodmFsdWU6IG51bWJlcikge1xuICAgIGNvbnN0IGxlbmd0aCA9IDE7XG4gICAgdGhpcy5tYWtlUm9vbUZvcihsZW5ndGg
|